diff --git a/FAQ.md b/FAQs.md similarity index 96% rename from FAQ.md rename to FAQs.md index 4a84bbf966..b889f2052d 100644 --- a/FAQ.md +++ b/FAQs.md @@ -12,14 +12,14 @@ the total number of constraints in the generate circuit can vary. To illustrate this, here are two examples to show the difference: ``` -const = 00000001 +constant = 00000001 variable = abcdefgh --------------------------------- output = 0000000h (1 constraint) ``` ``` -const = 01110001 +constant = 01110001 variable = abcdefgh --------------------------------- output = 0bcd000h (4 constraints) diff --git a/ast/src/errors/parser.rs b/ast/src/errors/parser.rs index c0726896cc..df679dc62b 100644 --- a/ast/src/errors/parser.rs +++ b/ast/src/errors/parser.rs @@ -17,7 +17,7 @@ pub enum ParserError { #[error("{}", _0)] SyntaxError(#[from] SyntaxError), - #[error("Unable to construct abstract syntax tree")] + #[error("Unable to construct program abstract syntax tree")] SyntaxTreeError, } diff --git a/ast/src/errors/syntax.rs b/ast/src/errors/syntax.rs index fa255b07f7..2bce3412d0 100644 --- a/ast/src/errors/syntax.rs +++ b/ast/src/errors/syntax.rs @@ -35,6 +35,11 @@ impl From> for SyntaxError { Rule::operation_div => "`/`".to_owned(), Rule::operation_pow => "`**`".to_owned(), + Rule::package => "package. Check package and import names for errors.".to_owned(), + Rule::package_name => { + "package name. Please use lowercase letters, numbers, and dashes `-` only.".to_owned() + } + rule => format!("{:?}", rule), }); diff --git a/ast/src/imports/mod.rs b/ast/src/imports/mod.rs index c2b4b01765..696656fb9f 100644 --- a/ast/src/imports/mod.rs +++ b/ast/src/imports/mod.rs @@ -10,5 +10,8 @@ pub use package::*; pub mod package_access; pub use package_access::*; +pub mod package_name; +pub use package_name::*; + pub mod star; pub use star::*; diff --git a/ast/src/imports/package.rs b/ast/src/imports/package.rs index b93d1de982..f8b34c4362 100644 --- a/ast/src/imports/package.rs +++ b/ast/src/imports/package.rs @@ -1,4 +1,8 @@ -use crate::{ast::Rule, common::Identifier, imports::PackageAccess, SpanDef}; +use crate::{ + ast::Rule, + imports::{PackageAccess, PackageName}, + SpanDef, +}; use pest::Span; use pest_ast::FromPest; @@ -7,7 +11,7 @@ use serde::Serialize; #[derive(Clone, Debug, FromPest, PartialEq, Serialize)] #[pest_ast(rule(Rule::package))] pub struct Package<'ast> { - pub name: Identifier<'ast>, + pub name: PackageName<'ast>, pub access: PackageAccess<'ast>, #[pest_ast(outer())] #[serde(with = "SpanDef")] diff --git a/ast/src/imports/package_name.rs b/ast/src/imports/package_name.rs new file mode 100644 index 0000000000..610dfb5bce --- /dev/null +++ b/ast/src/imports/package_name.rs @@ -0,0 +1,25 @@ +use crate::{ + ast::{span_into_string, Rule}, + SpanDef, +}; + +use pest::Span; +use pest_ast::FromPest; +use serde::Serialize; +use std::fmt; + +#[derive(Clone, Debug, FromPest, PartialEq, Serialize)] +#[pest_ast(rule(Rule::package_name))] +pub struct PackageName<'ast> { + #[pest_ast(outer(with(span_into_string)))] + pub value: String, + #[pest_ast(outer())] + #[serde(with = "SpanDef")] + pub span: Span<'ast>, +} + +impl<'ast> fmt::Display for PackageName<'ast> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.value) + } +} diff --git a/ast/src/leo.pest b/ast/src/leo.pest index c59edd2455..0ce0c2a3ec 100644 --- a/ast/src/leo.pest +++ b/ast/src/leo.pest @@ -389,8 +389,11 @@ input_tuple = _{ "(" ~ NEWLINE* ~ (input ~ ("," ~ NEWLINE* ~ input)* ~ ","?)? ~ // Declared in imports/import.rs import = { "import " ~ package ~ LINE_END} + +package_name = @{ ((ASCII_ALPHA_LOWER | ASCII_DIGIT) ~ ( "-" ~ (ASCII_ALPHA_LOWER | ASCII_DIGIT))*)+ } + // Declared in imports/package.rs -package = { identifier ~ "." ~ package_access } +package = { package_name ~ "." ~ package_access } // Declared in imports/package_access package_access = { diff --git a/compiler/src/definition/definitions.rs b/compiler/src/definition/definitions.rs index cf377444bc..9925340ec4 100644 --- a/compiler/src/definition/definitions.rs +++ b/compiler/src/definition/definitions.rs @@ -13,24 +13,24 @@ use snarkos_models::curves::{Field, PrimeField}; impl> ConstrainedProgram { pub fn store_definitions(&mut self, program: Program, imported_programs: &ImportParser) -> Result<(), ImportError> { - let program_name = program.name.clone(); + let program_name = program.name.trim_end_matches(".leo"); // evaluate all import statements and store imported definitions program .imports .iter() - .map(|import| self.store_import(program_name.clone(), import, imported_programs)) + .map(|import| self.store_import(program_name.to_owned(), import, imported_programs)) .collect::, ImportError>>()?; // evaluate and store all circuit definitions program.circuits.into_iter().for_each(|(identifier, circuit)| { - let resolved_circuit_name = new_scope(program_name.clone(), identifier.to_string()); + let resolved_circuit_name = new_scope(program_name.to_owned(), identifier.to_string()); self.store(resolved_circuit_name, ConstrainedValue::CircuitDefinition(circuit)); }); // evaluate and store all function definitions program.functions.into_iter().for_each(|(function_name, function)| { - let resolved_function_name = new_scope(program_name.clone(), function_name.to_string()); + let resolved_function_name = new_scope(program_name.to_owned(), function_name.to_string()); self.store(resolved_function_name, ConstrainedValue::Function(None, function)); }); diff --git a/compiler/src/import/store/import.rs b/compiler/src/import/store/import.rs index c13454f3be..9833330b5e 100644 --- a/compiler/src/import/store/import.rs +++ b/compiler/src/import/store/import.rs @@ -10,23 +10,19 @@ impl> ConstrainedProgram { import: &Import, imported_programs: &ImportParser, ) -> Result<(), ImportError> { - // get imported program name from import - // get imported symbols from from import + // fetch dependencies for the current import let imported_symbols = ImportedSymbols::from(import); for (package, symbol) in imported_symbols.symbols { - // get imported program from hashmap + // find imported program let program = imported_programs .get(&package) .ok_or(ImportError::unknown_package(import.package.name.clone()))?; - // resolve imported program's import statements - program - .imports - .iter() - .map(|import| self.store_import(package.clone(), import, imported_programs)) - .collect::, ImportError>>()?; + // parse imported program + self.store_definitions(program.clone(), imported_programs)?; + // store the imported symbol self.store_symbol(scope.clone(), package, &symbol, program)?; } diff --git a/compiler/src/import/store/symbol.rs b/compiler/src/import/store/symbol.rs index c618c6f6b5..dd20022607 100644 --- a/compiler/src/import/store/symbol.rs +++ b/compiler/src/import/store/symbol.rs @@ -11,6 +11,7 @@ impl> ConstrainedProgram { symbol: &ImportSymbol, program: &Program, ) -> Result<(), ImportError> { + // Store the symbol that was imported by another file if symbol.is_star() { // evaluate and store all circuit definitions program.circuits.iter().for_each(|(identifier, circuit)| { diff --git a/compiler/tests/import/basic.leo b/compiler/tests/import/basic.leo index ace5c1624f..03f7d892fe 100644 --- a/compiler/tests/import/basic.leo +++ b/compiler/tests/import/basic.leo @@ -1,4 +1,4 @@ -import test_import.foo; +import test-import.foo; function main() { assert_eq!(foo(), 1u32); diff --git a/compiler/tests/import/many_import.leo b/compiler/tests/import/many_import.leo index 1cbbea72e4..a699229614 100644 --- a/compiler/tests/import/many_import.leo +++ b/compiler/tests/import/many_import.leo @@ -1,4 +1,4 @@ -import test_import.( // local import +import test-import.( // local import Point, foo, ); diff --git a/compiler/tests/import/many_import_star.leo b/compiler/tests/import/many_import_star.leo index 90c6d7aad0..f27d08f991 100644 --- a/compiler/tests/import/many_import_star.leo +++ b/compiler/tests/import/many_import_star.leo @@ -1,4 +1,4 @@ -import test_import.*; // local import +import test-import.*; // local import import bar.*; // imports directory import import bar.baz.*; // imports directory import diff --git a/compiler/tests/import/mod.rs b/compiler/tests/import/mod.rs index b3b3d480c3..765b1ff65f 100644 --- a/compiler/tests/import/mod.rs +++ b/compiler/tests/import/mod.rs @@ -66,6 +66,54 @@ fn test_alias() { assert_satisfied(program); } +// naming tests +#[test] +#[ignore] +fn test_names_pass() { + set_local_dir(); + + let bytes = include_bytes!("names.leo"); + let program = parse_program(bytes).unwrap(); + + assert_satisfied(program); +} + +#[test] +#[ignore] +fn test_names_fail_1() { + set_local_dir(); + + let bytes = include_bytes!("names_dash_a.leo"); + assert!(parse_program(bytes).is_err()); +} + +#[test] +#[ignore] +fn test_names_fail_2() { + set_local_dir(); + + let bytes = include_bytes!("names_a_dash.leo"); + assert!(parse_program(bytes).is_err()); +} + +#[test] +#[ignore] +fn test_names_fail_3() { + set_local_dir(); + + let bytes = include_bytes!("names_underscore.leo"); + assert!(parse_program(bytes).is_err()); +} + +#[test] +#[ignore] +fn test_names_fail_4() { + set_local_dir(); + + let bytes = include_bytes!("names_dollar.leo"); + assert!(parse_program(bytes).is_err()); +} + // more complex tests #[test] #[ignore] diff --git a/compiler/tests/import/multiple.leo b/compiler/tests/import/multiple.leo index 0be311af36..0854d6e1c8 100644 --- a/compiler/tests/import/multiple.leo +++ b/compiler/tests/import/multiple.leo @@ -1,4 +1,4 @@ -import test_import.( +import test-import.( Point, foo ); diff --git a/compiler/tests/import/names.leo b/compiler/tests/import/names.leo new file mode 100644 index 0000000000..d3ce50829a --- /dev/null +++ b/compiler/tests/import/names.leo @@ -0,0 +1,5 @@ +import a0-f.foo; +import a-9.bar; +import hello-world.hello; + +function main() {} \ No newline at end of file diff --git a/compiler/tests/import/names_a_dash.leo b/compiler/tests/import/names_a_dash.leo new file mode 100644 index 0000000000..ec136176b2 --- /dev/null +++ b/compiler/tests/import/names_a_dash.leo @@ -0,0 +1,3 @@ +import a-.foo; + +function main() {} \ No newline at end of file diff --git a/compiler/tests/import/names_dash_a.leo b/compiler/tests/import/names_dash_a.leo new file mode 100644 index 0000000000..95ccb7e4a5 --- /dev/null +++ b/compiler/tests/import/names_dash_a.leo @@ -0,0 +1,3 @@ +import -a.foo; + +function main() {} \ No newline at end of file diff --git a/compiler/tests/import/names_dollar.leo b/compiler/tests/import/names_dollar.leo new file mode 100644 index 0000000000..e4eaec3719 --- /dev/null +++ b/compiler/tests/import/names_dollar.leo @@ -0,0 +1,3 @@ +import money$.foo; + +function main() {} \ No newline at end of file diff --git a/compiler/tests/import/names_underscore.leo b/compiler/tests/import/names_underscore.leo new file mode 100644 index 0000000000..c5822ebadd --- /dev/null +++ b/compiler/tests/import/names_underscore.leo @@ -0,0 +1,3 @@ +import hello_world.foo; + +function main() {} \ No newline at end of file diff --git a/compiler/tests/import/src/a-9.leo b/compiler/tests/import/src/a-9.leo new file mode 100644 index 0000000000..8cd9f87f14 --- /dev/null +++ b/compiler/tests/import/src/a-9.leo @@ -0,0 +1 @@ +function bar() {} \ No newline at end of file diff --git a/compiler/tests/import/src/a0-f.leo b/compiler/tests/import/src/a0-f.leo new file mode 100644 index 0000000000..c99ad3b713 --- /dev/null +++ b/compiler/tests/import/src/a0-f.leo @@ -0,0 +1 @@ +function foo() {} \ No newline at end of file diff --git a/compiler/tests/import/src/hello-world.leo b/compiler/tests/import/src/hello-world.leo new file mode 100644 index 0000000000..2d96e74c4c --- /dev/null +++ b/compiler/tests/import/src/hello-world.leo @@ -0,0 +1 @@ +function hello() {} \ No newline at end of file diff --git a/compiler/tests/import/src/test_import.leo b/compiler/tests/import/src/test-import.leo similarity index 100% rename from compiler/tests/import/src/test_import.leo rename to compiler/tests/import/src/test-import.leo diff --git a/compiler/tests/import/star.leo b/compiler/tests/import/star.leo index 4f347d6f93..4e546af535 100644 --- a/compiler/tests/import/star.leo +++ b/compiler/tests/import/star.leo @@ -1,4 +1,4 @@ -import test_import.*; +import test-import.*; function main() { let a = Point { x: 1u32, y: 0u32 }; diff --git a/input/src/errors/parser.rs b/input/src/errors/parser.rs index 89330d28d8..d09c6e9fe7 100644 --- a/input/src/errors/parser.rs +++ b/input/src/errors/parser.rs @@ -31,7 +31,7 @@ pub enum InputParserError { #[error("{}", _0)] SyntaxError(#[from] InputSyntaxError), - #[error("Unable to construct abstract syntax tree")] + #[error("Unable to construct program input abstract syntax tree")] SyntaxTreeError, } diff --git a/leo/commands/load.rs b/leo/commands/add.rs similarity index 91% rename from leo/commands/load.rs rename to leo/commands/add.rs index f91190297d..7a2ef9a4e8 100644 --- a/leo/commands/load.rs +++ b/leo/commands/add.rs @@ -13,16 +13,16 @@ use clap::ArgMatches; use std::{convert::TryFrom, env::current_dir}; #[derive(Debug)] -pub struct LoadCommand; +pub struct AddCommand; -impl CLI for LoadCommand { +impl CLI for AddCommand { type Options = (); type Output = (); const ABOUT: AboutType = "Install a package from the package manager (*)"; const ARGUMENTS: &'static [ArgumentType] = &[]; const FLAGS: &'static [FlagType] = &[]; - const NAME: NameType = "load"; + const NAME: NameType = "add"; const OPTIONS: &'static [OptionType] = &[]; const SUBCOMMANDS: &'static [SubCommandType] = &[]; @@ -39,7 +39,7 @@ impl CLI for LoadCommand { // Get the package name let _package_name = Manifest::try_from(&path)?.get_package_name(); - log::info!("Unimplemented - `leo load`"); + log::info!("Unimplemented - `leo add`"); Ok(()) } diff --git a/leo/commands/login.rs b/leo/commands/login.rs index ed0491941e..ec19137e07 100644 --- a/leo/commands/login.rs +++ b/leo/commands/login.rs @@ -1,19 +1,12 @@ // -// Usege: +// Usage: // // leo login // leo login -u username -p password // leo login // not yet implemented // -use crate::{ - cli::CLI, - cli_types::*, - errors::{ - CLIError::LoginError, - LoginError::{CannotGetToken, ConnectionUnavalaible, WrongLoginOrPassword}, - }, -}; +use crate::{cli::CLI, cli_types::*, errors::LoginError}; use lazy_static::lazy_static; use std::{ collections::HashMap, @@ -56,10 +49,15 @@ impl CLI for LoginCommand { type Options = (Option, Option, Option); type Output = String; - const ABOUT: AboutType = "Login to the package manager (*)"; + const ABOUT: AboutType = "Login to the Aleo Package Manager"; const ARGUMENTS: &'static [ArgumentType] = &[ // (name, description, required, index) - ("NAME", "Sets token for login to the package manager", false, 1u64), + ( + "NAME", + "Sets the authentication token for login to the package manager", + false, + 1u64, + ), ]; const FLAGS: &'static [FlagType] = &[]; const NAME: NameType = "login"; @@ -91,7 +89,7 @@ impl CLI for LoginCommand { fn output(options: Self::Options) -> Result { let token = match options { // Login using existing token - (Some(token), _, _) => token, + (Some(token), _, _) => Some(token), // Login using username and password (None, Some(username), Some(password)) => { @@ -107,37 +105,50 @@ impl CLI for LoginCommand { Ok(json) => json, Err(_error) => { log::error!("Wrong login or password"); - return Err(LoginError(WrongLoginOrPassword("Wrong login or password".into()))); + return Err(LoginError::WrongLoginOrPassword("Wrong login or password".into()).into()); } }, //Cannot connect to the server Err(_error) => { - return Err(LoginError(ConnectionUnavalaible( - "Could not connect to the package manager".into(), - ))); + return Err( + LoginError::NoConnectionFound("Could not connect to the package manager".into()).into(), + ); } }; match response.get("token") { - Some(token) => token.clone(), - None => return Err(LoginError(CannotGetToken("There is no token".into()))), + Some(token) => Some(token.clone()), + None => { + return Err(LoginError::CannotGetToken("No token was provided in the response".into()).into()); + } } } // Login using JWT (_, _, _) => { // TODO JWT - unimplemented!() + None } }; - // Create Leo credentials directory if it not exists - if !Path::new(LEO_CREDENTIALS_DIR).exists() { - create_dir(LEO_CREDENTIALS_DIR)?; - } + match token { + Some(token) => { + // Create Leo credentials directory if it not exists + if !Path::new(LEO_CREDENTIALS_DIR).exists() { + create_dir(LEO_CREDENTIALS_DIR)?; + } - LoginCommand::write_token(token.as_str())?; - log::info!("Successfully logged in"); - Ok(token) + LoginCommand::write_token(token.as_str())?; + + log::info!("Login successful."); + + Ok(token) + } + _ => { + log::error!("Failed to login. Please run `leo login -h` for help."); + + Err(LoginError::NoCredentialsProvided.into()) + } + } } } diff --git a/leo/commands/mod.rs b/leo/commands/mod.rs index 4fac06e973..2a3e109f8a 100644 --- a/leo/commands/mod.rs +++ b/leo/commands/mod.rs @@ -13,8 +13,8 @@ pub use self::init::*; pub mod lint; pub use self::lint::*; -pub mod load; -pub use self::load::*; +pub mod add; +pub use self::add::*; pub mod login; pub use self::login::*; @@ -37,8 +37,8 @@ pub use self::setup::*; pub mod test; pub use self::test::*; -pub mod unload; -pub use self::unload::*; +pub mod remove; +pub use self::remove::*; pub mod watch; pub use self::watch::*; diff --git a/leo/commands/publish.rs b/leo/commands/publish.rs index 4130011535..8fbbe37f56 100644 --- a/leo/commands/publish.rs +++ b/leo/commands/publish.rs @@ -8,11 +8,12 @@ use crate::{ CLIError::PublishError, }, }; -use clap::ArgMatches; use leo_package::{ outputs::OutputsDirectory, root::{Manifest, ZipFile}, }; + +use clap::ArgMatches; use reqwest::{ blocking::{multipart::Form, Client}, header::{HeaderMap, HeaderValue}, @@ -36,16 +37,8 @@ impl CLI for PublishCommand { type Options = (); type Output = Option; - const ABOUT: AboutType = "Publish the current package to the package manager (*)"; - const ARGUMENTS: &'static [ArgumentType] = &[ - // (name, description, required, index) - ( - "NAME", - "Sets the resulting package name, defaults to the directory name", - true, - 1u64, - ), - ]; + const ABOUT: AboutType = "Publish the current package to the Aleo Package Manager"; + const ARGUMENTS: &'static [ArgumentType] = &[]; const FLAGS: &'static [FlagType] = &[]; const NAME: NameType = "publish"; const OPTIONS: &'static [OptionType] = &[]; @@ -53,17 +46,12 @@ impl CLI for PublishCommand { #[cfg_attr(tarpaulin, skip)] fn parse(_arguments: &ArgMatches) -> Result { - // match arguments.value_of("NAME") { - // Some(name) => Ok((Some(name.to_string()),)), - // None => Ok((None,)), - // } Ok(()) } #[cfg_attr(tarpaulin, skip)] fn output(_options: Self::Options) -> Result { // 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 @@ -77,7 +65,9 @@ impl CLI for PublishCommand { // Create zip file let zip_file = ZipFile::new(&package_name); if zip_file.exists_at(&path) { - log::info!("Existing package zip file found. Skipping compression.") + log::debug!("Existing package zip file found. Clearing it to regenerate."); + // Remove the existing package zip file + ZipFile::new(&package_name).remove(&path)?; } else { zip_file.write(&path)?; } @@ -94,8 +84,8 @@ impl CLI for PublishCommand { let token = match LoginCommand::read_token() { Ok(token) => token, - // If not logged then try to login using JWT - Err(_errorr) => { + // If not logged in, then try logging in using JWT. + Err(_error) => { log::warn!("You should be logged before publish the package"); log::info!("Trying to log in using JWT..."); let options = (None, None, None); @@ -133,7 +123,7 @@ impl CLI for PublishCommand { } }; - log::info!("Packge published successfully"); + log::info!("Package published successfully"); Ok(Some(result.package_id)) } } diff --git a/leo/commands/unload.rs b/leo/commands/remove.rs similarity index 90% rename from leo/commands/unload.rs rename to leo/commands/remove.rs index cb9ca8c3fb..9ae66b64f1 100644 --- a/leo/commands/unload.rs +++ b/leo/commands/remove.rs @@ -13,16 +13,16 @@ use clap::ArgMatches; use std::{convert::TryFrom, env::current_dir}; #[derive(Debug)] -pub struct UnloadCommand; +pub struct RemoveCommand; -impl CLI for UnloadCommand { +impl CLI for RemoveCommand { type Options = (); type Output = (); const ABOUT: AboutType = "Uninstall a package from the current package (*)"; const ARGUMENTS: &'static [ArgumentType] = &[]; const FLAGS: &'static [FlagType] = &[]; - const NAME: NameType = "unload"; + const NAME: NameType = "remove"; const OPTIONS: &'static [OptionType] = &[]; const SUBCOMMANDS: &'static [SubCommandType] = &[]; @@ -40,7 +40,7 @@ impl CLI for UnloadCommand { // Get the package name let _package_name = Manifest::try_from(&path)?.get_package_name(); - log::info!("Unimplemented - `leo load`"); + log::info!("Unimplemented - `leo remove`"); Ok(()) } diff --git a/leo/commands/watch.rs b/leo/commands/watch.rs index f037e3bd09..dfb079bf87 100644 --- a/leo/commands/watch.rs +++ b/leo/commands/watch.rs @@ -31,7 +31,7 @@ impl CLI for WatchCommand { let mut watcher = watcher(tx, Duration::from_secs(INTERVAL)).unwrap(); watcher.watch(LEO_SOURCE_DIR, RecursiveMode::Recursive).unwrap(); - log::info!("Watching leo's source files"); + log::info!("Watching Leo source code"); loop { match rx.recv() { // See changes on the write event @@ -39,7 +39,7 @@ impl CLI for WatchCommand { let options = (); match BuildCommand::output(options) { Ok(_output) => { - log::info!("Build successfully"); + log::info!("Built successfully"); } Err(e) => { // Syntax error @@ -51,9 +51,11 @@ impl CLI for WatchCommand { Ok(_event) => {} // Watch error - Err(e) => println!("watch error: {:?}", e), + Err(e) => { + log::error!("watch error: {:?}", e) + // TODO (howardwu): Add graceful termination. + } } } - // Ok(()) } } diff --git a/leo/errors/commands/login.rs b/leo/errors/commands/login.rs index f05729a947..7db339c843 100644 --- a/leo/errors/commands/login.rs +++ b/leo/errors/commands/login.rs @@ -5,9 +5,12 @@ pub enum LoginError { #[error("{:?}", _0)] CannotGetToken(OsString), - #[error("connectin unavalaible {:?}", _0)] - ConnectionUnavalaible(OsString), + #[error("No connection found {:?}", _0)] + NoConnectionFound(OsString), - #[error("wrong login or password {:?}", _0)] + #[error("No login credentials were provided")] + NoCredentialsProvided, + + #[error("Wrong login or password {:?}", _0)] WrongLoginOrPassword(OsString), } diff --git a/leo/main.rs b/leo/main.rs index 06578f29ca..7cbab7f433 100644 --- a/leo/main.rs +++ b/leo/main.rs @@ -23,18 +23,18 @@ fn main() -> Result<(), CLIError> { NewCommand::new().display_order(0), InitCommand::new().display_order(1), BuildCommand::new().display_order(2), - TestCommand::new().display_order(3), - LintCommand::new().display_order(4), - LoadCommand::new().display_order(5), - UnloadCommand::new().display_order(6), - SetupCommand::new().display_order(7), - ProveCommand::new().display_order(8), - RunCommand::new().display_order(9), - LoginCommand::new().display_order(10), + WatchCommand::new().display_order(3), + TestCommand::new().display_order(4), + SetupCommand::new().display_order(5), + ProveCommand::new().display_order(6), + RunCommand::new().display_order(7), + LoginCommand::new().display_order(8), + AddCommand::new().display_order(9), + RemoveCommand::new().display_order(10), PublishCommand::new().display_order(11), DeployCommand::new().display_order(12), CleanCommand::new().display_order(13), - WatchCommand::new().display_order(14), + LintCommand::new().display_order(14), ]) .set_term_width(0) .get_matches(); @@ -43,18 +43,18 @@ fn main() -> Result<(), CLIError> { ("new", Some(arguments)) => NewCommand::process(arguments), ("init", Some(arguments)) => InitCommand::process(arguments), ("build", Some(arguments)) => BuildCommand::process(arguments), + ("watch", Some(arguments)) => WatchCommand::process(arguments), ("test", Some(arguments)) => TestCommand::process(arguments), - ("lint", Some(arguments)) => LintCommand::process(arguments), - ("load", Some(arguments)) => LoadCommand::process(arguments), - ("unload", Some(arguments)) => UnloadCommand::process(arguments), ("setup", Some(arguments)) => SetupCommand::process(arguments), ("prove", Some(arguments)) => ProveCommand::process(arguments), ("run", Some(arguments)) => RunCommand::process(arguments), ("login", Some(arguments)) => LoginCommand::process(arguments), + ("add", Some(arguments)) => AddCommand::process(arguments), + ("remove", Some(arguments)) => RemoveCommand::process(arguments), ("publish", Some(arguments)) => PublishCommand::process(arguments), ("deploy", Some(arguments)) => DeployCommand::process(arguments), ("clean", Some(arguments)) => CleanCommand::process(arguments), - ("watch", Some(arguments)) => WatchCommand::process(arguments), + ("lint", Some(arguments)) => LintCommand::process(arguments), _ => unreachable!(), } } diff --git a/package/src/errors/root/zip.rs b/package/src/errors/root/zip.rs index ca477d8167..1cf20e984b 100644 --- a/package/src/errors/root/zip.rs +++ b/package/src/errors/root/zip.rs @@ -13,6 +13,9 @@ pub enum ZipFileError { #[error("Cannot read from the provided file path - {:?}", _0)] FileReadError(PathBuf), + #[error("Cannot remove the provided file - {:?}", _0)] + FileRemovalError(PathBuf), + #[error("writing: {}", _0)] Writing(io::Error), diff --git a/package/src/root/zip.rs b/package/src/root/zip.rs index 48c8d08ea0..30acdf3d4e 100644 --- a/package/src/root/zip.rs +++ b/package/src/root/zip.rs @@ -16,7 +16,7 @@ use crate::{ use serde::Deserialize; use std::{ - fs::File, + fs::{self, File}, io::{Read, Write}, path::{Path, PathBuf}, }; @@ -80,7 +80,7 @@ impl ZipFile { // write file or directory if path.is_file() { - log::info!("\tadding file {:?} as {:?}", path, name); + log::info!("Adding file {:?} as {:?}", path, name); zip.start_file_from_path(name, options)?; let mut f = File::open(path)?; @@ -90,7 +90,7 @@ impl ZipFile { } 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); + log::info!("Adding directory {:?} as {:?}", path, name); zip.add_directory_from_path(name, options)?; } } @@ -102,6 +102,18 @@ impl ZipFile { Ok(()) } + /// Removes the zip file at the given path if it exists. Returns `true` on success, + /// `false` if the file doesn't exist, and `Error` if the file system fails during operation. + pub fn remove(&self, path: &PathBuf) -> Result { + let path = self.setup_file_path(path); + if !path.exists() { + return Ok(false); + } + + fs::remove_file(&path).map_err(|_| ZipFileError::FileRemovalError(path.clone()))?; + Ok(true) + } + fn setup_file_path(&self, path: &PathBuf) -> PathBuf { let mut path = path.to_owned(); if path.is_dir() { @@ -115,11 +127,12 @@ impl ZipFile { } fn is_excluded(path: &Path) -> bool { + log::debug!("Checking if {:?} is excluded", path); + // excluded directories: `input`, `output`, `imports` if path.ends_with(INPUTS_DIRECTORY_NAME.trim_end_matches("/")) | path.ends_with(OUTPUTS_DIRECTORY_NAME.trim_end_matches("/")) | path.ends_with(IMPORTS_DIRECTORY_NAME.trim_end_matches("/")) - | path.starts_with(INPUTS_DIRECTORY_NAME) { return true; } diff --git a/typed/src/common/identifier.rs b/typed/src/common/identifier.rs index 02a1b0a914..3a31e08599 100644 --- a/typed/src/common/identifier.rs +++ b/typed/src/common/identifier.rs @@ -1,5 +1,5 @@ use crate::Span; -use leo_ast::common::Identifier as AstIdentifier; +use leo_ast::{common::Identifier as AstIdentifier, imports::PackageName as AstPackageName}; use leo_input::common::Identifier as InputAstIdentifier; use serde::{ @@ -37,6 +37,15 @@ impl<'ast> From> for Identifier { } } +impl<'ast> From> for Identifier { + fn from(name: AstPackageName<'ast>) -> Self { + Self { + name: name.value, + span: Span::from(name.span), + } + } +} + impl<'ast> From> for Identifier { fn from(identifier: InputAstIdentifier<'ast>) -> Self { Self {