From d36d6b64ba65e08c8314b5c5d3e027bd019d23a4 Mon Sep 17 00:00:00 2001 From: raychu86 Date: Sun, 13 Sep 2020 17:09:56 -0700 Subject: [PATCH 01/11] Update [package] to [project] in manifest file --- package/src/root/manifest.rs | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/package/src/root/manifest.rs b/package/src/root/manifest.rs index bb33dd63ac..e8123f7432 100644 --- a/package/src/root/manifest.rs +++ b/package/src/root/manifest.rs @@ -33,14 +33,14 @@ pub struct Remote { #[derive(Deserialize)] pub struct Manifest { - pub package: Package, + pub project: Package, pub remote: Option, } impl Manifest { pub fn new(package_name: &str) -> Self { Self { - package: Package::new(package_name), + project: Package::new(package_name), remote: None, } } @@ -58,19 +58,19 @@ impl Manifest { } pub fn get_package_name(&self) -> String { - self.package.name.clone() + self.project.name.clone() } pub fn get_package_version(&self) -> String { - self.package.version.clone() + self.project.version.clone() } pub fn get_package_description(&self) -> Option { - self.package.description.clone() + self.project.description.clone() } pub fn get_package_license(&self) -> Option { - self.package.license.clone() + self.project.license.clone() } pub fn get_package_remote(&self) -> Option { @@ -90,7 +90,7 @@ impl Manifest { fn template(&self) -> String { format!( - r#"[package] + r#"[project] name = "{name}" version = "0.1.0" description = "The {name} package" @@ -99,7 +99,7 @@ license = "MIT" [remote] author = "[AUTHOR]" # Add your Aleo Package Manager username, team's name, or organization's name. "#, - name = self.package.name + name = self.project.name ) } } @@ -145,7 +145,15 @@ impl TryFrom<&PathBuf> for Manifest { if line.starts_with("[remote]") { new_remote_format_exists = true; } - new_toml += line; + + // If the old project format is being being used, update the toml file + // to use the new format instead. + if line.starts_with("[package]") { + new_toml += "[project]"; + } else { + new_toml += line; + } + new_toml += "\n"; } From 2a82a760f68ee7d94833e0cabf981b11c122222a Mon Sep 17 00:00:00 2001 From: raychu86 Date: Sun, 13 Sep 2020 17:13:14 -0700 Subject: [PATCH 02/11] Update examples --- examples/fibonacci/Leo.toml | 2 +- examples/fibonacci/README.md | 1 + examples/hello-world/Leo.toml | 2 +- examples/hello-world/README.md | 1 + examples/pedersen-hash/Leo.toml | 2 +- examples/pedersen-hash/README.md | 1 + examples/square-root/Leo.toml | 2 +- examples/square-root/README.md | 1 + 8 files changed, 8 insertions(+), 4 deletions(-) create mode 100644 examples/fibonacci/README.md create mode 100644 examples/hello-world/README.md create mode 100644 examples/pedersen-hash/README.md create mode 100644 examples/square-root/README.md diff --git a/examples/fibonacci/Leo.toml b/examples/fibonacci/Leo.toml index 85cc1b1916..74409f8b14 100644 --- a/examples/fibonacci/Leo.toml +++ b/examples/fibonacci/Leo.toml @@ -1,4 +1,4 @@ -[package] +[project] name = "fibonacci" version = "0.1.0" description = "Returns a fibonnaci sequence" diff --git a/examples/fibonacci/README.md b/examples/fibonacci/README.md new file mode 100644 index 0000000000..be8c859831 --- /dev/null +++ b/examples/fibonacci/README.md @@ -0,0 +1 @@ +# fibonacci diff --git a/examples/hello-world/Leo.toml b/examples/hello-world/Leo.toml index b3cde2b151..7255a801f9 100644 --- a/examples/hello-world/Leo.toml +++ b/examples/hello-world/Leo.toml @@ -1,4 +1,4 @@ -[package] +[project] name = "hello-world" version = "0.1.0" description = "Returns the sum of two u32 integers" diff --git a/examples/hello-world/README.md b/examples/hello-world/README.md new file mode 100644 index 0000000000..1534e6cdf3 --- /dev/null +++ b/examples/hello-world/README.md @@ -0,0 +1 @@ +# hello-world diff --git a/examples/pedersen-hash/Leo.toml b/examples/pedersen-hash/Leo.toml index 13b7d80257..5076066fa2 100644 --- a/examples/pedersen-hash/Leo.toml +++ b/examples/pedersen-hash/Leo.toml @@ -1,4 +1,4 @@ -[package] +[project] name = "pedersen-hash" version = "0.1.0" description = "A 256bit hash function" diff --git a/examples/pedersen-hash/README.md b/examples/pedersen-hash/README.md new file mode 100644 index 0000000000..341d98f707 --- /dev/null +++ b/examples/pedersen-hash/README.md @@ -0,0 +1 @@ +# pedersen-hash diff --git a/examples/square-root/Leo.toml b/examples/square-root/Leo.toml index 00235bcba1..9717d86062 100644 --- a/examples/square-root/Leo.toml +++ b/examples/square-root/Leo.toml @@ -1,4 +1,4 @@ -[package] +[project] name = "square-root" version = "0.1.0" description = "prove knowledge of the square root `a` of a number `b`" diff --git a/examples/square-root/README.md b/examples/square-root/README.md new file mode 100644 index 0000000000..8536c68b02 --- /dev/null +++ b/examples/square-root/README.md @@ -0,0 +1 @@ +# square-root From 515dc8204bf5b585d818932361967bba4b715db2 Mon Sep 17 00:00:00 2001 From: raychu86 Date: Sun, 13 Sep 2020 18:02:47 -0700 Subject: [PATCH 03/11] Add feature flag for updating the manifest --- Cargo.toml | 3 ++- package/Cargo.toml | 4 ++++ package/src/root/manifest.rs | 12 ++++++++---- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2a5cf15591..44cb477297 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -150,8 +150,9 @@ version = "0.5" version = "0.11.2" [features] -default = [ ] +default = [ "update_manifest" ] ci_skip = [ "leo-compiler/ci_skip" ] +update_manifest = [ "leo-package/update_manifest" ] [profile.release] opt-level = 3 diff --git a/package/Cargo.toml b/package/Cargo.toml index 5edfb9df1f..9c4b515196 100644 --- a/package/Cargo.toml +++ b/package/Cargo.toml @@ -41,3 +41,7 @@ version = "0.5" [dev-dependencies.lazy_static] version = "1.3.0" + +[features] +default = [ ] +update_manifest = [ ] \ No newline at end of file diff --git a/package/src/root/manifest.rs b/package/src/root/manifest.rs index e8123f7432..3fdeb73857 100644 --- a/package/src/root/manifest.rs +++ b/package/src/root/manifest.rs @@ -183,10 +183,14 @@ author = "{author}" } // Rewrite the toml file if it has been updated - if buffer != new_toml { - let mut file = File::create(&path).map_err(|error| ManifestError::Creating(MANIFEST_FILENAME, error))?; - file.write_all(new_toml.as_bytes()) - .map_err(|error| ManifestError::Writing(MANIFEST_FILENAME, error))?; + #[cfg(feature = "update_manifest")] + { + if buffer != new_toml { + let mut file = + File::create(&path).map_err(|error| ManifestError::Creating(MANIFEST_FILENAME, error))?; + file.write_all(new_toml.as_bytes()) + .map_err(|error| ManifestError::Writing(MANIFEST_FILENAME, error))?; + } } // Read the toml file From 5f5c887846f0809e55a8990815cdeb5fb802e92f Mon Sep 17 00:00:00 2001 From: raychu86 Date: Sun, 13 Sep 2020 18:12:19 -0700 Subject: [PATCH 04/11] Separate the update_manifest feature into remote and package features --- package/Cargo.toml | 4 ++- package/src/root/manifest.rs | 48 ++++++++++++++++++++---------------- 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/package/Cargo.toml b/package/Cargo.toml index 9c4b515196..990a36e9da 100644 --- a/package/Cargo.toml +++ b/package/Cargo.toml @@ -44,4 +44,6 @@ version = "1.3.0" [features] default = [ ] -update_manifest = [ ] \ No newline at end of file +update_manifest = [ "update_remote", "update_project" ] +update_remote = [ ] +update_project = [ ] \ No newline at end of file diff --git a/package/src/root/manifest.rs b/package/src/root/manifest.rs index 3fdeb73857..d1a18c7427 100644 --- a/package/src/root/manifest.rs +++ b/package/src/root/manifest.rs @@ -133,24 +133,34 @@ impl TryFrom<&PathBuf> for Manifest { // Read each individual line of the toml file for line in buffer.lines() { // Determine if the old remote format is being used - if line.starts_with("remote") { - let remote = line - .split("=") // Split the line as 'remote' = '"{author}/{package_name}"' - .collect::>()[1]; // Fetch just '"{author}/{package_name}"' - old_remote_format = Some(remote); - continue; - } + #[cfg(feature = "update_remote")] + { + if line.starts_with("remote") { + let remote = line + .split("=") // Split the line as 'remote' = '"{author}/{package_name}"' + .collect::>()[1]; // Fetch just '"{author}/{package_name}"' + old_remote_format = Some(remote); + continue; + } - // Determine if the new remote format is being used - if line.starts_with("[remote]") { - new_remote_format_exists = true; + // Determine if the new remote format is being used + if line.starts_with("[remote]") { + new_remote_format_exists = true; + } } // If the old project format is being being used, update the toml file // to use the new format instead. - if line.starts_with("[package]") { - new_toml += "[project]"; - } else { + #[cfg(feature = "update_project")] + { + if line.starts_with("[package]") { + new_toml += "[project]"; + } else { + new_toml += line; + } + } + #[cfg(not(feature = "update_project"))] + { new_toml += line; } @@ -183,14 +193,10 @@ author = "{author}" } // Rewrite the toml file if it has been updated - #[cfg(feature = "update_manifest")] - { - if buffer != new_toml { - let mut file = - File::create(&path).map_err(|error| ManifestError::Creating(MANIFEST_FILENAME, error))?; - file.write_all(new_toml.as_bytes()) - .map_err(|error| ManifestError::Writing(MANIFEST_FILENAME, error))?; - } + if buffer != new_toml { + let mut file = File::create(&path).map_err(|error| ManifestError::Creating(MANIFEST_FILENAME, error))?; + file.write_all(new_toml.as_bytes()) + .map_err(|error| ManifestError::Writing(MANIFEST_FILENAME, error))?; } // Read the toml file From beb4ed420f6af8835b85df794aea96ab125d408d Mon Sep 17 00:00:00 2001 From: raychu86 Date: Sun, 13 Sep 2020 18:23:17 -0700 Subject: [PATCH 05/11] Refactor feature names --- Cargo.toml | 3 +-- package/Cargo.toml | 8 ++++---- package/src/root/manifest.rs | 6 +++--- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 44cb477297..2a5cf15591 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -150,9 +150,8 @@ version = "0.5" version = "0.11.2" [features] -default = [ "update_manifest" ] +default = [ ] ci_skip = [ "leo-compiler/ci_skip" ] -update_manifest = [ "leo-package/update_manifest" ] [profile.release] opt-level = 3 diff --git a/package/Cargo.toml b/package/Cargo.toml index 990a36e9da..4aad98d528 100644 --- a/package/Cargo.toml +++ b/package/Cargo.toml @@ -43,7 +43,7 @@ version = "0.5" version = "1.3.0" [features] -default = [ ] -update_manifest = [ "update_remote", "update_project" ] -update_remote = [ ] -update_project = [ ] \ No newline at end of file +default = [ "manifest_refactors" ] +manifest_refactors = [ "manifest_refactor_remote", "manifest_refactor_project" ] +manifest_refactor_remote = [ ] +manifest_refactor_project = [ ] \ No newline at end of file diff --git a/package/src/root/manifest.rs b/package/src/root/manifest.rs index d1a18c7427..a04b30f4bf 100644 --- a/package/src/root/manifest.rs +++ b/package/src/root/manifest.rs @@ -133,7 +133,7 @@ impl TryFrom<&PathBuf> for Manifest { // Read each individual line of the toml file for line in buffer.lines() { // Determine if the old remote format is being used - #[cfg(feature = "update_remote")] + #[cfg(feature = "manifest_refactor_remote")] { if line.starts_with("remote") { let remote = line @@ -151,7 +151,7 @@ impl TryFrom<&PathBuf> for Manifest { // If the old project format is being being used, update the toml file // to use the new format instead. - #[cfg(feature = "update_project")] + #[cfg(feature = "manifest_refactor_project")] { if line.starts_with("[package]") { new_toml += "[project]"; @@ -159,7 +159,7 @@ impl TryFrom<&PathBuf> for Manifest { new_toml += line; } } - #[cfg(not(feature = "update_project"))] + #[cfg(not(feature = "manifest_refactor_project"))] { new_toml += line; } From a036dc8ac3a1ae297779689b66198e4482f2ffe7 Mon Sep 17 00:00:00 2001 From: raychu86 Date: Sun, 13 Sep 2020 18:49:45 -0700 Subject: [PATCH 06/11] Fix manifest update logic --- package/Cargo.toml | 4 +- package/src/root/manifest.rs | 75 ++++++++++++++++++++++-------------- 2 files changed, 49 insertions(+), 30 deletions(-) diff --git a/package/Cargo.toml b/package/Cargo.toml index 4aad98d528..54804fb86b 100644 --- a/package/Cargo.toml +++ b/package/Cargo.toml @@ -44,6 +44,6 @@ version = "1.3.0" [features] default = [ "manifest_refactors" ] -manifest_refactors = [ "manifest_refactor_remote", "manifest_refactor_project" ] +manifest_refactors = [ "manifest_refactor_project", "manifest_refactor_remote" ] +manifest_refactor_project = [ ] manifest_refactor_remote = [ ] -manifest_refactor_project = [ ] \ No newline at end of file diff --git a/package/src/root/manifest.rs b/package/src/root/manifest.rs index a04b30f4bf..ac7ef2cb03 100644 --- a/package/src/root/manifest.rs +++ b/package/src/root/manifest.rs @@ -128,43 +128,56 @@ impl TryFrom<&PathBuf> for Manifest { let mut old_remote_format: Option<&str> = None; let mut new_remote_format_exists = false; - let mut new_toml = "".to_owned(); + // Toml file adhering to the new format. + let mut final_toml = "".to_owned(); + + // New Toml file format that should be written based on feature flags. + let mut refactored_toml = "".to_owned(); // Read each individual line of the toml file for line in buffer.lines() { // Determine if the old remote format is being used - #[cfg(feature = "manifest_refactor_remote")] - { - if line.starts_with("remote") { - let remote = line - .split("=") // Split the line as 'remote' = '"{author}/{package_name}"' - .collect::>()[1]; // Fetch just '"{author}/{package_name}"' - old_remote_format = Some(remote); - continue; - } + if line.starts_with("remote") { + let remote = line + .split("=") // Split the line as 'remote' = '"{author}/{package_name}"' + .collect::>()[1]; // Fetch just '"{author}/{package_name}"' + old_remote_format = Some(remote); - // Determine if the new remote format is being used - if line.starts_with("[remote]") { - new_remote_format_exists = true; + // Retain the old remote format if the `manifest_refactor_remote` is not enabled + #[cfg(not(feature = "manifest_refactor_remote"))] + { + refactored_toml += line; + refactored_toml += "\n"; } + continue; + } + + // Determine if the new remote format is being used + if line.starts_with("[remote]") { + new_remote_format_exists = true; } // If the old project format is being being used, update the toml file // to use the new format instead. - #[cfg(feature = "manifest_refactor_project")] - { - if line.starts_with("[package]") { - new_toml += "[project]"; - } else { - new_toml += line; + if line.starts_with("[package]") { + final_toml += "[project]"; + + // Refactor the old project format if the `manifest_refactor_project` is enabled + #[cfg(feature = "manifest_refactor_project")] + { + refactored_toml += "[project]"; } - } - #[cfg(not(feature = "manifest_refactor_project"))] - { - new_toml += line; + #[cfg(not(feature = "manifest_refactor_project"))] + { + refactored_toml += line; + } + } else { + final_toml += line; + refactored_toml += line; } - new_toml += "\n"; + final_toml += "\n"; + refactored_toml += "\n"; } // Update the remote format @@ -188,18 +201,24 @@ author = "{author}" ); // Append the new remote to the bottom of the manifest file. - new_toml += &new_remote; + final_toml += &new_remote; + + // Add the new remote format if the `manifest_refactor_remote` is enabled + #[cfg(feature = "manifest_refactor_remote")] + { + refactored_toml += &new_remote; + } } } // Rewrite the toml file if it has been updated - if buffer != new_toml { + if buffer != refactored_toml { let mut file = File::create(&path).map_err(|error| ManifestError::Creating(MANIFEST_FILENAME, error))?; - file.write_all(new_toml.as_bytes()) + file.write_all(refactored_toml.as_bytes()) .map_err(|error| ManifestError::Writing(MANIFEST_FILENAME, error))?; } // Read the toml file - Ok(toml::from_str(&new_toml).map_err(|error| ManifestError::Parsing(MANIFEST_FILENAME, error))?) + Ok(toml::from_str(&final_toml).map_err(|error| ManifestError::Parsing(MANIFEST_FILENAME, error))?) } } From ec9daf62e647ed828b5be44670749c9a584a08b7 Mon Sep 17 00:00:00 2001 From: raychu86 Date: Sun, 13 Sep 2020 21:53:09 -0700 Subject: [PATCH 07/11] Implement package tests --- package/src/root/manifest.rs | 16 +-- package/tests/initialize.rs | 192 ------------------------- package/tests/initialize/initialize.rs | 134 +++++++++++++++++ package/tests/initialize/mod.rs | 17 +++ package/tests/manifest/manifest.rs | 169 ++++++++++++++++++++++ package/tests/manifest/mod.rs | 17 +++ package/tests/mod.rs | 73 ++++++++++ 7 files changed, 415 insertions(+), 203 deletions(-) delete mode 100644 package/tests/initialize.rs create mode 100644 package/tests/initialize/initialize.rs create mode 100644 package/tests/initialize/mod.rs create mode 100644 package/tests/manifest/manifest.rs create mode 100644 package/tests/manifest/mod.rs create mode 100644 package/tests/mod.rs diff --git a/package/src/root/manifest.rs b/package/src/root/manifest.rs index ac7ef2cb03..485516c06d 100644 --- a/package/src/root/manifest.rs +++ b/package/src/root/manifest.rs @@ -144,8 +144,7 @@ impl TryFrom<&PathBuf> for Manifest { old_remote_format = Some(remote); // Retain the old remote format if the `manifest_refactor_remote` is not enabled - #[cfg(not(feature = "manifest_refactor_remote"))] - { + if cfg!(not(feature = "manifest_refactor_remote")) { refactored_toml += line; refactored_toml += "\n"; } @@ -163,13 +162,9 @@ impl TryFrom<&PathBuf> for Manifest { final_toml += "[project]"; // Refactor the old project format if the `manifest_refactor_project` is enabled - #[cfg(feature = "manifest_refactor_project")] - { - refactored_toml += "[project]"; - } - #[cfg(not(feature = "manifest_refactor_project"))] - { - refactored_toml += line; + match cfg!(feature = "manifest_refactor_project") { + true => refactored_toml += "[project]", + false => refactored_toml += line, } } else { final_toml += line; @@ -204,8 +199,7 @@ author = "{author}" final_toml += &new_remote; // Add the new remote format if the `manifest_refactor_remote` is enabled - #[cfg(feature = "manifest_refactor_remote")] - { + if cfg!(feature = "manifest_refactor_remote") { refactored_toml += &new_remote; } } diff --git a/package/tests/initialize.rs b/package/tests/initialize.rs deleted file mode 100644 index 62dc23eb85..0000000000 --- a/package/tests/initialize.rs +++ /dev/null @@ -1,192 +0,0 @@ -// Copyright (C) 2019-2020 Aleo Systems Inc. -// This file is part of the Leo library. - -// The Leo library is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// The Leo library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with the Leo library. If not, see . - -use lazy_static::lazy_static; -use std::{ - cell::RefCell, - env, - fs, - path::PathBuf, - sync::atomic::{AtomicUsize, Ordering}, -}; - -const PACKAGE_TEST_DIRECTORY: &str = "package-testing"; - -thread_local! { - /// Establish a test id for each test. - static TEST_ID: RefCell> = RefCell::new(None); -} - -lazy_static! { - /// Create a testing directory for packages in `target/` - static ref TEST_DIR: PathBuf = { - let mut path = env::current_exe().unwrap(); - path.pop(); // Remove executable name - path.pop(); // Remove 'debug' - - // Attempt to point at the `target` directory - if path.file_name().and_then(|s| s.to_str()) != Some("target") { - path.pop(); - } - - path.push(PACKAGE_TEST_DIRECTORY); - fs::create_dir_all(&path).unwrap(); - - path - }; -} - -/// Create a new directory for each test based on the ID of the test. -fn test_dir() -> PathBuf { - static NEXT_ID: AtomicUsize = AtomicUsize::new(0); - - let id = NEXT_ID.fetch_add(1, Ordering::Relaxed); - TEST_ID.with(|n| *n.borrow_mut() = Some(id)); - - let path: PathBuf = TEST_DIR.join(&format!("t{}", id)).into(); - - if path.exists() { - if let Err(e) = fs::remove_dir_all(&path) { - panic!("failed to remove {:?}: {:?}", &path, e) - } - } - - fs::create_dir_all(&path).unwrap(); - - path -} - -// Tests for package initialization -mod initialize_package { - use super::*; - use leo_package::{ - inputs::{InputFile, InputsDirectory, StateFile}, - package::Package, - root::Manifest, - source::{LibraryFile, MainFile, SourceDirectory}, - }; - - const TEST_PACKAGE_NAME: &str = "test-package"; - - #[test] - fn initialize_valid_package() { - let test_directory = test_dir(); - - // Ensure a package can be initialized at the `test_directory` - assert!(Package::can_initialize(TEST_PACKAGE_NAME, false, &test_directory)); - - // Initialize a package at the `test_directory` - assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory).is_ok()); - - // Ensure a package is initialized at the `test_directory` - assert!(Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory)); - } - - #[test] - #[ignore] - fn initialize_fails_with_invalid_package_names() { - unimplemented!() - } - - #[test] - fn initialize_fails_with_existing_manifest() { - let test_directory = test_dir(); - - // Ensure a package can be initialized at the `test_directory` - assert!(Package::can_initialize(TEST_PACKAGE_NAME, false, &test_directory)); - - // Manually add a manifest file to the `test_directory` - Manifest::new(TEST_PACKAGE_NAME).write_to(&test_directory).unwrap(); - - // Attempt to initialize a package at the `test_directory` - assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory).is_err()); - - // Ensure package is not initialized at the `test_directory` - assert!(!Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory)); - } - - #[test] - fn initialize_fails_with_existing_library_file() { - let test_directory = test_dir(); - - // Ensure a package can be initialized at the `test_directory` - assert!(Package::can_initialize(TEST_PACKAGE_NAME, true, &test_directory)); - - // Manually add a source directory and a library file to the `test_directory` - SourceDirectory::create(&test_directory).unwrap(); - LibraryFile::new(TEST_PACKAGE_NAME).write_to(&test_directory).unwrap(); - - // Attempt to initialize a package at the `test_directory` - assert!(Package::initialize(TEST_PACKAGE_NAME, true, &test_directory).is_err()); - - // Ensure package is not initialized at the `test_directory` - assert!(!Package::is_initialized(TEST_PACKAGE_NAME, true, &test_directory)); - } - - #[test] - fn initialize_fails_with_existing_input_file() { - let test_directory = test_dir(); - - // Ensure a package can be initialized at the `test_directory` - assert!(Package::can_initialize(TEST_PACKAGE_NAME, false, &test_directory)); - - // Manually add an inputs directory and an input file to the `test_directory` - InputsDirectory::create(&test_directory).unwrap(); - InputFile::new(TEST_PACKAGE_NAME).write_to(&test_directory).unwrap(); - - // Attempt to initialize a package at the `test_directory` - assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory).is_err()); - - // Ensure package is not initialized at the `test_directory` - assert!(!Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory)); - } - - #[test] - fn initialize_fails_with_existing_state_file() { - let test_directory = test_dir(); - - // Ensure a package can be initialized at the `test_directory` - assert!(Package::can_initialize(TEST_PACKAGE_NAME, false, &test_directory)); - - // Manually add an inputs directory and a state file to the `test_directory` - InputsDirectory::create(&test_directory).unwrap(); - StateFile::new(TEST_PACKAGE_NAME).write_to(&test_directory).unwrap(); - - // Attempt to initialize a package at the `test_directory` - assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory).is_err()); - - // Ensure package is not initialized at the `test_directory` - assert!(!Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory)); - } - - #[test] - fn initialize_fails_with_existing_main_file() { - let test_directory = test_dir(); - - // Ensure a package can be initialized at the `test_directory` - assert!(Package::can_initialize(TEST_PACKAGE_NAME, false, &test_directory)); - - // Manually add a source directory and a main file to the `test_directory` - SourceDirectory::create(&test_directory).unwrap(); - MainFile::new(TEST_PACKAGE_NAME).write_to(&test_directory).unwrap(); - - // Attempt to initialize a package at the `test_directory` - assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory).is_err()); - - // Ensure package is not initialized at the `test_directory` - assert!(!Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory)); - } -} diff --git a/package/tests/initialize/initialize.rs b/package/tests/initialize/initialize.rs new file mode 100644 index 0000000000..82763d4124 --- /dev/null +++ b/package/tests/initialize/initialize.rs @@ -0,0 +1,134 @@ +// Copyright (C) 2019-2020 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +use crate::test_dir; +use leo_package::{ + inputs::{InputFile, InputsDirectory, StateFile}, + package::Package, + root::Manifest, + source::{LibraryFile, MainFile, SourceDirectory}, +}; + +const TEST_PACKAGE_NAME: &str = "test-package"; + +#[test] +fn initialize_valid_package() { + let test_directory = test_dir(); + + // Ensure a package can be initialized at the `test_directory` + assert!(Package::can_initialize(TEST_PACKAGE_NAME, false, &test_directory)); + + // Initialize a package at the `test_directory` + assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory).is_ok()); + + // Ensure a package is initialized at the `test_directory` + assert!(Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory)); +} + +#[test] +#[ignore] +fn initialize_fails_with_invalid_package_names() { + unimplemented!() +} + +#[test] +fn initialize_fails_with_existing_manifest() { + let test_directory = test_dir(); + + // Ensure a package can be initialized at the `test_directory` + assert!(Package::can_initialize(TEST_PACKAGE_NAME, false, &test_directory)); + + // Manually add a manifest file to the `test_directory` + Manifest::new(TEST_PACKAGE_NAME).write_to(&test_directory).unwrap(); + + // Attempt to initialize a package at the `test_directory` + assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory).is_err()); + + // Ensure package is not initialized at the `test_directory` + assert!(!Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory)); +} + +#[test] +fn initialize_fails_with_existing_library_file() { + let test_directory = test_dir(); + + // Ensure a package can be initialized at the `test_directory` + assert!(Package::can_initialize(TEST_PACKAGE_NAME, true, &test_directory)); + + // Manually add a source directory and a library file to the `test_directory` + SourceDirectory::create(&test_directory).unwrap(); + LibraryFile::new(TEST_PACKAGE_NAME).write_to(&test_directory).unwrap(); + + // Attempt to initialize a package at the `test_directory` + assert!(Package::initialize(TEST_PACKAGE_NAME, true, &test_directory).is_err()); + + // Ensure package is not initialized at the `test_directory` + assert!(!Package::is_initialized(TEST_PACKAGE_NAME, true, &test_directory)); +} + +#[test] +fn initialize_fails_with_existing_input_file() { + let test_directory = test_dir(); + + // Ensure a package can be initialized at the `test_directory` + assert!(Package::can_initialize(TEST_PACKAGE_NAME, false, &test_directory)); + + // Manually add an inputs directory and an input file to the `test_directory` + InputsDirectory::create(&test_directory).unwrap(); + InputFile::new(TEST_PACKAGE_NAME).write_to(&test_directory).unwrap(); + + // Attempt to initialize a package at the `test_directory` + assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory).is_err()); + + // Ensure package is not initialized at the `test_directory` + assert!(!Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory)); +} + +#[test] +fn initialize_fails_with_existing_state_file() { + let test_directory = test_dir(); + + // Ensure a package can be initialized at the `test_directory` + assert!(Package::can_initialize(TEST_PACKAGE_NAME, false, &test_directory)); + + // Manually add an inputs directory and a state file to the `test_directory` + InputsDirectory::create(&test_directory).unwrap(); + StateFile::new(TEST_PACKAGE_NAME).write_to(&test_directory).unwrap(); + + // Attempt to initialize a package at the `test_directory` + assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory).is_err()); + + // Ensure package is not initialized at the `test_directory` + assert!(!Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory)); +} + +#[test] +fn initialize_fails_with_existing_main_file() { + let test_directory = test_dir(); + + // Ensure a package can be initialized at the `test_directory` + assert!(Package::can_initialize(TEST_PACKAGE_NAME, false, &test_directory)); + + // Manually add a source directory and a main file to the `test_directory` + SourceDirectory::create(&test_directory).unwrap(); + MainFile::new(TEST_PACKAGE_NAME).write_to(&test_directory).unwrap(); + + // Attempt to initialize a package at the `test_directory` + assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory).is_err()); + + // Ensure package is not initialized at the `test_directory` + assert!(!Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory)); +} diff --git a/package/tests/initialize/mod.rs b/package/tests/initialize/mod.rs new file mode 100644 index 0000000000..c0fbdb773b --- /dev/null +++ b/package/tests/initialize/mod.rs @@ -0,0 +1,17 @@ +// Copyright (C) 2019-2020 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +pub mod initialize; diff --git a/package/tests/manifest/manifest.rs b/package/tests/manifest/manifest.rs new file mode 100644 index 0000000000..afce5bfa0a --- /dev/null +++ b/package/tests/manifest/manifest.rs @@ -0,0 +1,169 @@ +// Copyright (C) 2019-2020 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +// Tests for package manifest + +use crate::test_dir; +use leo_package::root::{Manifest, MANIFEST_FILENAME}; + +use std::{ + convert::TryFrom, + fs::File, + io::{Read, Write}, + path::PathBuf, +}; + +const OLD_MANIFEST_FORMAT: &str = r#"[package] +name = "test-package" +version = "0.1.0" +description = "Testing manifest updates." +license = "MIT" +remote = "author/test-package" +"#; + +const NEW_REMOTE_FORMAT: &str = r#" +[remote] +author = "author" +"#; + +const OLD_PROJECT_FORMAT: &str = "[package]"; +const NEW_PROJECT_FORMAT: &str = "[project]"; + +/// Create a manifest file with outdated formatting. +fn create_outdated_manifest_file(path: PathBuf) -> PathBuf { + let mut path = path.to_owned(); + if path.is_dir() { + path.push(PathBuf::from(MANIFEST_FILENAME)); + } + + let mut file = File::create(&path).unwrap(); + file.write_all(OLD_MANIFEST_FORMAT.as_bytes()).unwrap(); + + path +} + +/// Read the manifest file into a string. +fn read_manifest_file(path: &PathBuf) -> String { + let mut file = File::open(path.clone()).unwrap(); + let size = file.metadata().unwrap().len() as usize; + + let mut buffer = String::with_capacity(size); + file.read_to_string(&mut buffer).unwrap(); + + buffer +} + +/// Read the manifest file and check that the remote format is updated. +fn remote_is_updated(path: &PathBuf) -> bool { + let manifest_string = read_manifest_file(&path); + for line in manifest_string.lines() { + if line.starts_with("remote") { + return false; + } + } + + manifest_string.contains(NEW_REMOTE_FORMAT) +} + +/// Read the manifest file and check that the project format is updated. +fn project_is_updated(path: &PathBuf) -> bool { + let manifest_string = read_manifest_file(&path); + + !manifest_string.contains(OLD_PROJECT_FORMAT) && manifest_string.contains(NEW_PROJECT_FORMAT) +} + +#[test] +#[cfg_attr( + any(feature = "manifest_refactor_project", feature = "manifest_refactor_remote"), + ignore +)] +fn test_manifest_no_refactors() { + // Create an outdated manifest file. + let test_directory = test_dir(); + let manifest_path = create_outdated_manifest_file(test_directory); + + // Load the manifest file, and discard the new struct. + let _manifest = Manifest::try_from(&manifest_path).unwrap(); + + // Check that the manifest file project has NOT been updated. + assert!(!project_is_updated(&manifest_path)); + + // Check that the manifest file remote has NOT been updated. + assert!(!remote_is_updated(&manifest_path)); +} + +#[test] +#[cfg_attr( + any(feature = "manifest_refactor_project", not(feature = "manifest_refactor_remote")), + ignore +)] +fn test_manifest_refactor_remote() { + // Create an outdated manifest file. + let test_directory = test_dir(); + let manifest_path = create_outdated_manifest_file(test_directory); + + // Load the manifest file, and discard the new struct. + let _manifest = Manifest::try_from(&manifest_path).unwrap(); + + // Check that the manifest file project has NOT been updated. + assert!(!project_is_updated(&manifest_path)); + + // Check that the manifest file remote has been updated. + assert!(remote_is_updated(&manifest_path)); +} + +#[test] +#[cfg_attr( + any(not(feature = "manifest_refactor_project"), feature = "manifest_refactor_remote"), + ignore +)] +fn test_manifest_refactor_project() { + // Create an outdated manifest file. + let test_directory = test_dir(); + let manifest_path = create_outdated_manifest_file(test_directory); + + // Load the manifest file, and discard the new struct. + let _manifest = Manifest::try_from(&manifest_path).unwrap(); + + // Check that the manifest file project has been updated. + assert!(project_is_updated(&manifest_path)); + + // Check that the manifest file remote has NOT been updated. + assert!(!remote_is_updated(&manifest_path)); +} + +#[test] +#[cfg_attr( + any( + not(feature = "manifest_refactor_project"), + not(feature = "manifest_refactor_remote") + ), + ignore +)] +fn test_manifest_refactors() { + // Create an outdated manifest file. + let test_directory = test_dir(); + let manifest_path = create_outdated_manifest_file(test_directory); + + // Load the manifest file, and discard the new struct. + let _manifest = Manifest::try_from(&manifest_path).unwrap(); + + // Check that the manifest file project has been updated. + assert!(project_is_updated(&manifest_path)); + + // Check that the manifest file remote has been updated. + assert!(remote_is_updated(&manifest_path)); +} diff --git a/package/tests/manifest/mod.rs b/package/tests/manifest/mod.rs new file mode 100644 index 0000000000..10d357ff78 --- /dev/null +++ b/package/tests/manifest/mod.rs @@ -0,0 +1,17 @@ +// Copyright (C) 2019-2020 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +pub mod manifest; diff --git a/package/tests/mod.rs b/package/tests/mod.rs new file mode 100644 index 0000000000..0fe5d2f794 --- /dev/null +++ b/package/tests/mod.rs @@ -0,0 +1,73 @@ +// Copyright (C) 2019-2020 Aleo Systems Inc. +// This file is part of the Leo library. + +// The Leo library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// The Leo library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with the Leo library. If not, see . + +pub mod initialize; +pub mod manifest; + +use lazy_static::lazy_static; +use std::{ + cell::RefCell, + env, + fs, + path::PathBuf, + sync::atomic::{AtomicUsize, Ordering}, +}; + +const PACKAGE_TEST_DIRECTORY: &str = "package-testing"; + +thread_local! { + /// Establish a test id for each test. + pub static TEST_ID: RefCell> = RefCell::new(None); +} + +lazy_static! { + /// Create a testing directory for packages in `target/` + pub static ref TEST_DIR: PathBuf = { + let mut path = env::current_exe().unwrap(); + path.pop(); // Remove executable name + path.pop(); // Remove 'debug' + + // Attempt to point at the `target` directory + if path.file_name().and_then(|s| s.to_str()) != Some("target") { + path.pop(); + } + + path.push(PACKAGE_TEST_DIRECTORY); + fs::create_dir_all(&path).unwrap(); + + path + }; +} + +/// Create a new directory for each test based on the ID of the test. +pub(crate) fn test_dir() -> PathBuf { + static NEXT_ID: AtomicUsize = AtomicUsize::new(0); + + let id = NEXT_ID.fetch_add(1, Ordering::Relaxed); + TEST_ID.with(|n| *n.borrow_mut() = Some(id)); + + let path: PathBuf = TEST_DIR.join(&format!("t{}", id)).into(); + + if path.exists() { + if let Err(e) = fs::remove_dir_all(&path) { + panic!("failed to remove {:?}: {:?}", &path, e) + } + } + + fs::create_dir_all(&path).unwrap(); + + path +} From dd31352bc6529b69734f25323e451f87797dd880 Mon Sep 17 00:00:00 2001 From: raychu86 Date: Sun, 13 Sep 2020 21:53:53 -0700 Subject: [PATCH 08/11] Add package test workflow --- .github/workflows/ci.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fc4ae82088..53bf3ea38a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -96,6 +96,34 @@ jobs: command: test args: --release --all --features ci_skip --no-fail-fast + test-package: + name: Test Package + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - stable + - nightly + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Install Rust (${{ matrix.rust }}) + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + override: true + + - name: Install cargo-all-features + run: | + cargo install cargo-all-features + + - name: Test + run: | + cd packages + cargo test-all-features + codecov: name: Code Coverage runs-on: ubuntu-latest From 7fb89df7c85616b79f8b791dc6dfe7c85190a4cb Mon Sep 17 00:00:00 2001 From: raychu86 Date: Sun, 13 Sep 2020 21:59:43 -0700 Subject: [PATCH 09/11] Fix workflow directory --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 53bf3ea38a..7c18c50c9c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -121,7 +121,7 @@ jobs: - name: Test run: | - cd packages + cd leo/packages cargo test-all-features codecov: From 1efb4440bc9d8245f76953793efa0b1a54c5a958 Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 18 Sep 2020 11:36:41 -0700 Subject: [PATCH 10/11] fix incorrect directory name --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7c18c50c9c..c4390bba2b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -121,7 +121,7 @@ jobs: - name: Test run: | - cd leo/packages + cd leo/package cargo test-all-features codecov: From c38d6322c95a274fec6afca8771ccc5a740d9a85 Mon Sep 17 00:00:00 2001 From: collin Date: Fri, 18 Sep 2020 11:39:26 -0700 Subject: [PATCH 11/11] fix incorrect directory name --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c4390bba2b..6749f22c9f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -121,7 +121,7 @@ jobs: - name: Test run: | - cd leo/package + cd package cargo test-all-features codecov: