adds name substitution on leo new and init

- only adds a name if user is already logged in
- if not, puts [AUTHOR] as it was previously
- before publishing author field is checked in Leo.toml and better error message returned
This commit is contained in:
damirka 2021-04-12 16:54:37 +03:00
parent ab033ff857
commit f3c97390ee
9 changed files with 99 additions and 27 deletions

View File

@ -1,7 +1,12 @@
# leo login & logout # leo login & logout
$LEO new my-app && cd my-app || exit 1
$LEO login -u "$ALEO_PM_USERNAME" -p "$ALEO_PM_PASSWORD" $LEO login -u "$ALEO_PM_USERNAME" -p "$ALEO_PM_PASSWORD"
$LEO new my-app && cd my-app || exit 1
# verify that in Leo.toml there's a line with $ALEO_PM_USERNAME;
# because at the time of calling `leo new` user is logged in and we're expecting substitution
[[ $(cat Leo.toml | grep "\[$ALEO_PM_USERNAME\]" | wc -l) -eq 1 ]] || exit 1
$LEO add howard/silly-sudoku $LEO add howard/silly-sudoku
$LEO remove silly-sudoku $LEO remove silly-sudoku
$LEO logout $LEO logout

View File

@ -1,4 +1,9 @@
$LEO new hello-world $LEO new hello-world
ls -la ls -la
cd hello-world && ls -la cd hello-world && ls -la
# verify that in Leo.toml there's a placeholder for author
# because at the time of calling `leo new` user is not logged in
[[ $(cat Leo.toml | grep "\[AUTHOR\]" | wc -l) -eq 1 ]] || exit 1
$LEO run $LEO run

View File

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License // 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/>. // along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{commands::Command, context::Context}; use crate::{commands::Command, config::*, context::Context};
use leo_package::LeoPackage; use leo_package::LeoPackage;
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
@ -43,6 +43,11 @@ impl Command for Init {
// Derive the package directory path. // Derive the package directory path.
let path = current_dir()?; let path = current_dir()?;
// Check that the current package directory path exists.
if !path.exists() {
return Err(anyhow!("Directory does not exist"));
}
// Check that the given package name is valid. // Check that the given package name is valid.
let package_name = path let package_name = path
.file_stem() .file_stem()
@ -53,12 +58,9 @@ impl Command for Init {
return Err(anyhow!("Invalid Leo project name")); return Err(anyhow!("Invalid Leo project name"));
} }
// Check that the current package directory path exists. let username = read_username().ok();
if !path.exists() {
return Err(anyhow!("Directory does not exist"));
}
LeoPackage::initialize(&package_name, false, &path)?; LeoPackage::initialize(&package_name, false, &path, username)?;
Ok(()) Ok(())
} }

View File

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License // 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/>. // along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::{commands::Command, context::Context}; use crate::{commands::Command, config::*, context::Context};
use leo_package::LeoPackage; use leo_package::LeoPackage;
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
@ -49,6 +49,8 @@ impl Command for New {
return Err(anyhow!("Invalid Leo project name")); return Err(anyhow!("Invalid Leo project name"));
} }
let username = read_username().ok();
// Derive the package directory path. // Derive the package directory path.
let mut path = current_dir()?; let mut path = current_dir()?;
path.push(&package_name); path.push(&package_name);
@ -61,7 +63,7 @@ impl Command for New {
// Create the package directory // Create the package directory
fs::create_dir_all(&path).map_err(|err| anyhow!("Could not create directory {}", err))?; fs::create_dir_all(&path).map_err(|err| anyhow!("Could not create directory {}", err))?;
LeoPackage::initialize(&package_name, false, &path)?; LeoPackage::initialize(&package_name, false, &path, username)?;
Ok(()) Ok(())
} }

View File

@ -19,7 +19,10 @@ use crate::{
commands::Command, commands::Command,
context::{Context, PACKAGE_MANAGER_URL}, context::{Context, PACKAGE_MANAGER_URL},
}; };
use leo_package::{outputs::OutputsDirectory, root::ZipFile}; use leo_package::{
outputs::OutputsDirectory,
root::{ZipFile, AUTHOR_PLACEHOLDER},
};
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use reqwest::{ use reqwest::{
@ -70,11 +73,19 @@ impl Command for Publish {
}; };
let package_remote = manifest.get_package_remote().unwrap(); let package_remote = manifest.get_package_remote().unwrap();
let username = package_remote.clone().author;
// Create the output directory // Prevent most common error before accessing API.
if username == AUTHOR_PLACEHOLDER {
return Err(anyhow!(
"Package author is not set. Specify package author in [remote] section of Leo.toml"
));
}
// Create the output directory.
OutputsDirectory::create(&path)?; OutputsDirectory::create(&path)?;
// Create zip file // Create zip file.
let zip_file = ZipFile::new(&package_name); let zip_file = ZipFile::new(&package_name);
if zip_file.exists_at(&path) { if zip_file.exists_at(&path) {
tracing::debug!("Existing package zip file found. Clearing it to regenerate."); tracing::debug!("Existing package zip file found. Clearing it to regenerate.");

View File

@ -33,8 +33,13 @@ pub struct LeoPackage;
impl LeoPackage { impl LeoPackage {
/// Initializes a Leo package at the given path. /// Initializes a Leo package at the given path.
pub fn initialize(package_name: &str, is_lib: bool, path: &Path) -> Result<(), PackageError> { pub fn initialize(
package::Package::initialize(package_name, is_lib, path) package_name: &str,
is_lib: bool,
path: &Path,
author: Option<String>,
) -> Result<(), PackageError> {
package::Package::initialize(package_name, is_lib, path, author)
} }
/// Returns `true` if the given Leo package name is valid. /// Returns `true` if the given Leo package name is valid.

View File

@ -197,7 +197,12 @@ impl Package {
} }
/// Creates a package at the given path /// Creates a package at the given path
pub fn initialize(package_name: &str, is_lib: bool, path: &Path) -> Result<(), PackageError> { pub fn initialize(
package_name: &str,
is_lib: bool,
path: &Path,
author: Option<String>,
) -> Result<(), PackageError> {
// First, verify that this directory is not already initialized as a Leo package. // First, verify that this directory is not already initialized as a Leo package.
{ {
if !Self::can_initialize(package_name, is_lib, path) { if !Self::can_initialize(package_name, is_lib, path) {
@ -210,7 +215,7 @@ impl Package {
// Next, initialize this directory as a Leo package. // Next, initialize this directory as a Leo package.
{ {
// Create the manifest file. // Create the manifest file.
Manifest::new(&package_name)?.write_to(&path)?; Manifest::new(&package_name, author)?.write_to(&path)?;
// Verify that the .gitignore file does not exist. // Verify that the .gitignore file does not exist.
if !Gitignore::exists_at(&path) { if !Gitignore::exists_at(&path) {

View File

@ -26,6 +26,7 @@ use std::{
}; };
pub const MANIFEST_FILENAME: &str = "Leo.toml"; pub const MANIFEST_FILENAME: &str = "Leo.toml";
pub const AUTHOR_PLACEHOLDER: &str = "[AUTHOR]";
#[derive(Clone, Deserialize)] #[derive(Clone, Deserialize)]
pub struct Remote { pub struct Remote {
@ -39,10 +40,10 @@ pub struct Manifest {
} }
impl Manifest { impl Manifest {
pub fn new(package_name: &str) -> Result<Self, ManifestError> { pub fn new(package_name: &str, author: Option<String>) -> Result<Self, ManifestError> {
Ok(Self { Ok(Self {
project: Package::new(package_name)?, project: Package::new(package_name)?,
remote: None, remote: author.map(|author| Remote { author }),
}) })
} }
@ -90,6 +91,11 @@ impl Manifest {
} }
fn template(&self) -> String { fn template(&self) -> String {
let author = self
.remote
.clone()
.map_or(AUTHOR_PLACEHOLDER.to_string(), |remote| remote.author);
format!( format!(
r#"[project] r#"[project]
name = "{name}" name = "{name}"
@ -98,9 +104,10 @@ description = "The {name} package"
license = "MIT" license = "MIT"
[remote] [remote]
author = "[AUTHOR]" # Add your Aleo Package Manager username, team's name, or organization's name. author = "{author}" # Add your Aleo Package Manager username, team's name, or organization's name.
"#, "#,
name = self.project.name name = self.project.name,
author = author
) )
} }
} }

View File

@ -32,7 +32,29 @@ fn initialize_valid_package() {
assert!(Package::can_initialize(TEST_PACKAGE_NAME, false, &test_directory)); assert!(Package::can_initialize(TEST_PACKAGE_NAME, false, &test_directory));
// Initialize a package at the `test_directory` // Initialize a package at the `test_directory`
assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory).is_ok()); assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory, None).is_ok());
// Ensure a package is initialized at the `test_directory`
assert!(Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory));
}
#[test]
fn initialize_valid_package_with_author() {
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,
Some(String::from("test_user"))
)
.is_ok()
);
// Ensure a package is initialized at the `test_directory` // Ensure a package is initialized at the `test_directory`
assert!(Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory)); assert!(Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory));
@ -52,13 +74,13 @@ fn initialize_fails_with_existing_manifest() {
assert!(Package::can_initialize(TEST_PACKAGE_NAME, false, &test_directory)); assert!(Package::can_initialize(TEST_PACKAGE_NAME, false, &test_directory));
// Manually add a manifest file to the `test_directory` // Manually add a manifest file to the `test_directory`
Manifest::new(TEST_PACKAGE_NAME) Manifest::new(TEST_PACKAGE_NAME, None)
.unwrap() .unwrap()
.write_to(&test_directory) .write_to(&test_directory)
.unwrap(); .unwrap();
// Attempt to initialize a package at the `test_directory` // Attempt to initialize a package at the `test_directory`
assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory).is_err()); assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory, None).is_err());
// Ensure package is not initialized at the `test_directory` // Ensure package is not initialized at the `test_directory`
assert!(!Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory)); assert!(!Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory));
@ -76,7 +98,7 @@ fn initialize_fails_with_existing_library_file() {
LibraryFile::new(TEST_PACKAGE_NAME).write_to(&test_directory).unwrap(); LibraryFile::new(TEST_PACKAGE_NAME).write_to(&test_directory).unwrap();
// Attempt to initialize a package at the `test_directory` // Attempt to initialize a package at the `test_directory`
assert!(Package::initialize(TEST_PACKAGE_NAME, true, &test_directory).is_err()); assert!(Package::initialize(TEST_PACKAGE_NAME, true, &test_directory, None).is_err());
// Ensure package is not initialized at the `test_directory` // Ensure package is not initialized at the `test_directory`
assert!(!Package::is_initialized(TEST_PACKAGE_NAME, true, &test_directory)); assert!(!Package::is_initialized(TEST_PACKAGE_NAME, true, &test_directory));
@ -94,7 +116,15 @@ fn initialize_fails_with_existing_input_file() {
InputFile::new(TEST_PACKAGE_NAME).write_to(&test_directory).unwrap(); InputFile::new(TEST_PACKAGE_NAME).write_to(&test_directory).unwrap();
// Attempt to initialize a package at the `test_directory` // Attempt to initialize a package at the `test_directory`
assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory).is_err()); assert!(
Package::initialize(
TEST_PACKAGE_NAME,
false,
&test_directory,
Some(String::from("test_user"))
)
.is_err()
);
// Ensure package is not initialized at the `test_directory` // Ensure package is not initialized at the `test_directory`
assert!(!Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory)); assert!(!Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory));
@ -112,7 +142,7 @@ fn initialize_fails_with_existing_state_file() {
StateFile::new(TEST_PACKAGE_NAME).write_to(&test_directory).unwrap(); StateFile::new(TEST_PACKAGE_NAME).write_to(&test_directory).unwrap();
// Attempt to initialize a package at the `test_directory` // Attempt to initialize a package at the `test_directory`
assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory).is_err()); assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory, None).is_err());
// Ensure package is not initialized at the `test_directory` // Ensure package is not initialized at the `test_directory`
assert!(!Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory)); assert!(!Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory));
@ -130,7 +160,7 @@ fn initialize_fails_with_existing_main_file() {
MainFile::new(TEST_PACKAGE_NAME).write_to(&test_directory).unwrap(); MainFile::new(TEST_PACKAGE_NAME).write_to(&test_directory).unwrap();
// Attempt to initialize a package at the `test_directory` // Attempt to initialize a package at the `test_directory`
assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory).is_err()); assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory, None).is_err());
// Ensure package is not initialized at the `test_directory` // Ensure package is not initialized at the `test_directory`
assert!(!Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory)); assert!(!Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory));