mirror of
https://github.com/AleoHQ/leo.git
synced 2024-11-29 11:43:28 +03:00
Complete command
This commit is contained in:
parent
93b47602dd
commit
83065845df
@ -1,4 +1,4 @@
|
|||||||
use crate::commands::cli_types::*;
|
use crate::cli_types::*;
|
||||||
use crate::errors::CLIError;
|
use crate::errors::CLIError;
|
||||||
|
|
||||||
use clap::{App, AppSettings, Arg, ArgMatches, SubCommand};
|
use clap::{App, AppSettings, Arg, ArgMatches, SubCommand};
|
||||||
@ -64,5 +64,5 @@ pub trait CLI {
|
|||||||
fn parse(arguments: &ArgMatches) -> Result<Self::Options, CLIError>;
|
fn parse(arguments: &ArgMatches) -> Result<Self::Options, CLIError>;
|
||||||
|
|
||||||
#[cfg_attr(tarpaulin, skip)]
|
#[cfg_attr(tarpaulin, skip)]
|
||||||
fn output(&mut self, options: Self::Options) -> Result<(), CLIError>;
|
fn output(options: Self::Options) -> Result<(), CLIError>;
|
||||||
}
|
}
|
63
leo/commands/init.rs
Normal file
63
leo/commands/init.rs
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
use crate::{cli::*, cli_types::*};
|
||||||
|
use crate::directories::SourceDirectory;
|
||||||
|
use crate::errors::{CLIError, InitError};
|
||||||
|
use crate::manifest::Manifest;
|
||||||
|
|
||||||
|
use clap::ArgMatches;
|
||||||
|
use std::env::current_dir;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct InitCommand;
|
||||||
|
|
||||||
|
impl CLI for InitCommand {
|
||||||
|
type Options = Option<String>;
|
||||||
|
|
||||||
|
const NAME: NameType = "init";
|
||||||
|
const ABOUT: AboutType = "Creates a new Leo package (include -h for more options)";
|
||||||
|
const FLAGS: &'static [FlagType] = &[];
|
||||||
|
const OPTIONS: &'static [OptionType] = &[];
|
||||||
|
const SUBCOMMANDS: &'static [SubCommandType] = &[];
|
||||||
|
|
||||||
|
#[cfg_attr(tarpaulin, skip)]
|
||||||
|
fn parse(_arguments: &ArgMatches) -> Result<Self::Options, CLIError> {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(tarpaulin, skip)]
|
||||||
|
fn output(options: Self::Options) -> Result<(), CLIError> {
|
||||||
|
let name = options;
|
||||||
|
let path = current_dir()?;
|
||||||
|
|
||||||
|
// Derive the package name
|
||||||
|
let package_name = match name {
|
||||||
|
Some(name) => name,
|
||||||
|
None => path
|
||||||
|
.file_stem()
|
||||||
|
.ok_or_else(|| InitError::ProjectNameInvalid(path.as_os_str().to_owned()))?
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Verify the directory exists
|
||||||
|
if !path.exists() {
|
||||||
|
return Err(InitError::DirectoryDoesNotExist(path.as_os_str().to_owned()).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify a manifest file does not already exist
|
||||||
|
if Manifest::exists_at(&path) {
|
||||||
|
return Err(InitError::PackageAlreadyExists(path.as_os_str().to_owned()).into());
|
||||||
|
}
|
||||||
|
Manifest::new(&package_name).write_to(&path)?;
|
||||||
|
|
||||||
|
// Create the source directory
|
||||||
|
SourceDirectory::create(&path)?;
|
||||||
|
|
||||||
|
// if !MainFile::exists_at(&path) {
|
||||||
|
// MainFile::new(&package_name)
|
||||||
|
// .write_to(&path)
|
||||||
|
// .map_err(Error::MainFile)?;
|
||||||
|
// }
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
@ -1,66 +0,0 @@
|
|||||||
use crate::commands::{cli::*, cli_types::*};
|
|
||||||
use crate::errors::{CLIError, ManifestError, NewError};
|
|
||||||
use crate::manifest::Manifest;
|
|
||||||
|
|
||||||
use clap::{ArgMatches, Values};
|
|
||||||
use colored::*;
|
|
||||||
use rand::{rngs::StdRng, Rng};
|
|
||||||
use rand_core::SeedableRng;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use serde_json::from_str;
|
|
||||||
use std::{fmt, fmt::Display, fs, str::FromStr};
|
|
||||||
use std::path::PathBuf;
|
|
||||||
use structopt::StructOpt;
|
|
||||||
|
|
||||||
#[derive(Debug, StructOpt)]
|
|
||||||
pub struct InitCommand {
|
|
||||||
#[structopt(parse(from_os_str))]
|
|
||||||
path: PathBuf,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CLI for InitCommand {
|
|
||||||
type Options = ();
|
|
||||||
|
|
||||||
const NAME: NameType = "init";
|
|
||||||
const ABOUT: AboutType = "Creates a new Leo package (include -h for more options)";
|
|
||||||
const FLAGS: &'static [FlagType] = &[];
|
|
||||||
const OPTIONS: &'static [OptionType] = &[];
|
|
||||||
const SUBCOMMANDS: &'static [SubCommandType] = &[];
|
|
||||||
|
|
||||||
#[cfg_attr(tarpaulin, skip)]
|
|
||||||
fn parse(arguments: &ArgMatches) -> Result<Self::Options, CLIError> {
|
|
||||||
let mut options = ();
|
|
||||||
// options.parse(arguments, &["count", "format", "json", "network"]);
|
|
||||||
//
|
|
||||||
// match arguments.subcommand() {
|
|
||||||
// ("hd", Some(arguments)) => {
|
|
||||||
// options.subcommand = Some("hd".into());
|
|
||||||
// options.parse(arguments, &["count", "json", "network"]);
|
|
||||||
// options.parse(arguments, &["derivation", "language", "password", "word count"]);
|
|
||||||
// }
|
|
||||||
// _ => {}
|
|
||||||
// };
|
|
||||||
|
|
||||||
Ok(options)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg_attr(tarpaulin, skip)]
|
|
||||||
fn output(&mut self, options: Self::Options) -> Result<(), CLIError> {
|
|
||||||
let package_name = self.path
|
|
||||||
.file_stem()
|
|
||||||
.ok_or_else(|| NewError::ProjectNameInvalid(self.path.as_os_str().to_owned()))?
|
|
||||||
.to_string_lossy()
|
|
||||||
.to_string();
|
|
||||||
|
|
||||||
if self.path.exists() {
|
|
||||||
return Err(NewError::DirectoryAlreadyExists(self.path.as_os_str().to_owned()).into());
|
|
||||||
}
|
|
||||||
fs::create_dir_all(&self.path).map_err(|error| {
|
|
||||||
NewError::CreatingRootDirectory(self.path.as_os_str().to_owned(), error)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Manifest::new(&package_name).write_to(&self.path).map_err(NewError::ManifestError)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,2 +0,0 @@
|
|||||||
pub mod init;
|
|
||||||
pub use self::init::*;
|
|
@ -1,6 +1,2 @@
|
|||||||
#[cfg_attr(tarpaulin, skip)]
|
|
||||||
pub mod cli;
|
|
||||||
pub mod cli_types;
|
|
||||||
|
|
||||||
pub mod init;
|
pub mod init;
|
||||||
pub use self::init::*;
|
pub use self::init::*;
|
||||||
|
2
leo/directories/mod.rs
Normal file
2
leo/directories/mod.rs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
pub mod source;
|
||||||
|
pub use self::source::*;
|
61
leo/directories/source.rs
Normal file
61
leo/directories/source.rs
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
use crate::errors::SourceDirectoryError;
|
||||||
|
|
||||||
|
use std::fs;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
pub(self) static DIRECTORY_NAME_DEFAULT: &str = "src/";
|
||||||
|
|
||||||
|
static SOURCE_FILE_EXTENSION_DEFAULT: &str = "leo";
|
||||||
|
|
||||||
|
pub struct SourceDirectory;
|
||||||
|
|
||||||
|
impl SourceDirectory {
|
||||||
|
/// Creates a directory at the provided path with the default directory name.
|
||||||
|
pub fn create(path: &PathBuf) -> Result<(), SourceDirectoryError> {
|
||||||
|
let mut path = path.to_owned();
|
||||||
|
if path.is_dir() && !path.ends_with(DIRECTORY_NAME_DEFAULT) {
|
||||||
|
path.push(PathBuf::from(DIRECTORY_NAME_DEFAULT));
|
||||||
|
}
|
||||||
|
|
||||||
|
fs::create_dir_all(&path).map_err(SourceDirectoryError::Creating)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a list of files in the source directory.
|
||||||
|
pub fn files(path: &PathBuf) -> Result<Vec<PathBuf>, SourceDirectoryError> {
|
||||||
|
let mut path = path.to_owned();
|
||||||
|
path.push(PathBuf::from(DIRECTORY_NAME_DEFAULT));
|
||||||
|
let directory = fs::read_dir(&path).map_err(SourceDirectoryError::Reading)?;
|
||||||
|
|
||||||
|
let mut file_paths = Vec::new();
|
||||||
|
for file_entry in directory.into_iter() {
|
||||||
|
let file_entry = file_entry.map_err(SourceDirectoryError::GettingFileEntry)?;
|
||||||
|
let file_path = file_entry.path();
|
||||||
|
|
||||||
|
// Verify that the entry is structured as a valid file
|
||||||
|
let file_type = file_entry
|
||||||
|
.file_type()
|
||||||
|
.map_err(|error| SourceDirectoryError::GettingFileType(file_path.as_os_str().to_owned(), error))?;
|
||||||
|
if !file_type.is_file() {
|
||||||
|
return Err(SourceDirectoryError::InvalidFileType(
|
||||||
|
file_path.as_os_str().to_owned(),
|
||||||
|
file_type,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that the file has the default file extension
|
||||||
|
let file_extension = file_path
|
||||||
|
.extension()
|
||||||
|
.ok_or_else(|| SourceDirectoryError::GettingFileExtension(file_path.as_os_str().to_owned()))?;
|
||||||
|
if file_extension != SOURCE_FILE_EXTENSION_DEFAULT {
|
||||||
|
return Err(SourceDirectoryError::InvalidFileExtension(
|
||||||
|
file_path.as_os_str().to_owned(),
|
||||||
|
file_extension.to_owned(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
file_paths.push(file_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(file_paths)
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
use crate::errors::{ManifestError, NewError};
|
use crate::errors::{ManifestError, InitError, SourceDirectoryError};
|
||||||
|
|
||||||
#[derive(Debug, Fail)]
|
#[derive(Debug, Fail)]
|
||||||
pub enum CLIError {
|
pub enum CLIError {
|
||||||
@ -9,7 +9,10 @@ pub enum CLIError {
|
|||||||
ManifestError(ManifestError),
|
ManifestError(ManifestError),
|
||||||
|
|
||||||
#[fail(display = "{}", _0)]
|
#[fail(display = "{}", _0)]
|
||||||
NewError(NewError),
|
InitError(InitError),
|
||||||
|
|
||||||
|
#[fail(display = "{}", _0)]
|
||||||
|
SourceDirectoryError(SourceDirectoryError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ManifestError> for CLIError {
|
impl From<ManifestError> for CLIError {
|
||||||
@ -18,14 +21,26 @@ impl From<ManifestError> for CLIError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<NewError> for CLIError {
|
impl From<InitError> for CLIError {
|
||||||
fn from(error: NewError) -> Self {
|
fn from(error: InitError) -> Self {
|
||||||
CLIError::NewError(error)
|
CLIError::InitError(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<SourceDirectoryError> for CLIError {
|
||||||
|
fn from(error: SourceDirectoryError) -> Self {
|
||||||
|
CLIError::SourceDirectoryError(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<serde_json::error::Error> for CLIError {
|
impl From<serde_json::error::Error> for CLIError {
|
||||||
fn from(error: serde_json::error::Error) -> Self {
|
fn from(error: serde_json::error::Error) -> Self {
|
||||||
CLIError::Crate("serde_json", format!("{:?}", error))
|
CLIError::Crate("serde_json", format!("{}", error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<std::io::Error> for CLIError {
|
||||||
|
fn from(error: std::io::Error) -> Self {
|
||||||
|
CLIError::Crate("std::io", format!("{}", error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,24 +4,27 @@ use std::ffi::OsString;
|
|||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
#[derive(Debug, Fail)]
|
#[derive(Debug, Fail)]
|
||||||
pub enum NewError {
|
pub enum InitError {
|
||||||
|
|
||||||
#[fail(display = "root directory {:?} creating: {}", _0, _1)]
|
#[fail(display = "root directory {:?} creating: {}", _0, _1)]
|
||||||
CreatingRootDirectory(OsString, io::Error),
|
CreatingRootDirectory(OsString, io::Error),
|
||||||
|
|
||||||
#[fail(display = "directory {:?} already exists", _0)]
|
#[fail(display = "directory {:?} does not exist", _0)]
|
||||||
DirectoryAlreadyExists(OsString),
|
DirectoryDoesNotExist(OsString),
|
||||||
|
|
||||||
#[fail(display = "{}", _0)]
|
#[fail(display = "{}", _0)]
|
||||||
ManifestError(ManifestError),
|
ManifestError(ManifestError),
|
||||||
|
|
||||||
|
#[fail(display = "package at path {:?} already exists", _0)]
|
||||||
|
PackageAlreadyExists(OsString),
|
||||||
|
|
||||||
#[fail(display = "package name is missing - {:?}", _0)]
|
#[fail(display = "package name is missing - {:?}", _0)]
|
||||||
ProjectNameInvalid(OsString),
|
ProjectNameInvalid(OsString),
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ManifestError> for NewError {
|
impl From<ManifestError> for InitError {
|
||||||
fn from(error: ManifestError) -> Self {
|
fn from(error: ManifestError) -> Self {
|
||||||
NewError::ManifestError(error)
|
InitError::ManifestError(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,2 +1,2 @@
|
|||||||
pub mod new;
|
pub mod init;
|
||||||
pub use self::new::*;
|
pub use self::init::*;
|
||||||
|
2
leo/errors/directory/mod.rs
Normal file
2
leo/errors/directory/mod.rs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
pub mod source;
|
||||||
|
pub use self::source::*;
|
27
leo/errors/directory/source.rs
Normal file
27
leo/errors/directory/source.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
use std::{ffi::OsString, fs::FileType, io};
|
||||||
|
|
||||||
|
#[derive(Debug, Fail)]
|
||||||
|
pub enum SourceDirectoryError {
|
||||||
|
|
||||||
|
#[fail(display = "creating: {}", _0)]
|
||||||
|
Creating(io::Error),
|
||||||
|
|
||||||
|
#[fail(display = "file entry getting: {}", _0)]
|
||||||
|
GettingFileEntry(io::Error),
|
||||||
|
|
||||||
|
#[fail(display = "file {:?} extension getting", _0)]
|
||||||
|
GettingFileExtension(OsString),
|
||||||
|
|
||||||
|
#[fail(display = "file {:?} type getting: {}", _0, _1)]
|
||||||
|
GettingFileType(OsString, io::Error),
|
||||||
|
|
||||||
|
#[fail(display = "invalid file {:?} extension: {:?}", _0, _1)]
|
||||||
|
InvalidFileExtension(OsString, OsString),
|
||||||
|
|
||||||
|
#[fail(display = "invalid file {:?} type: {:?}", _0, _1)]
|
||||||
|
InvalidFileType(OsString, FileType),
|
||||||
|
|
||||||
|
#[fail(display = "reading: {}", _0)]
|
||||||
|
Reading(io::Error),
|
||||||
|
|
||||||
|
}
|
@ -4,5 +4,8 @@ pub use self::cli::*;
|
|||||||
pub mod commands;
|
pub mod commands;
|
||||||
pub use self::commands::*;
|
pub use self::commands::*;
|
||||||
|
|
||||||
|
pub mod directory;
|
||||||
|
pub use self::directory::*;
|
||||||
|
|
||||||
pub mod manifest;
|
pub mod manifest;
|
||||||
pub use self::manifest::*;
|
pub use self::manifest::*;
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate failure;
|
extern crate failure;
|
||||||
|
|
||||||
|
#[cfg_attr(tarpaulin, skip)]
|
||||||
|
pub mod cli;
|
||||||
|
pub mod cli_types;
|
||||||
pub mod commands;
|
pub mod commands;
|
||||||
|
pub mod directories;
|
||||||
pub mod errors;
|
pub mod errors;
|
||||||
pub mod manifest;
|
pub mod manifest;
|
||||||
|
@ -110,7 +110,7 @@
|
|||||||
// //
|
// //
|
||||||
// }
|
// }
|
||||||
|
|
||||||
use leo::commands::{cli::*, InitCommand};
|
use leo::{cli::*, commands::*};
|
||||||
use leo::errors::CLIError;
|
use leo::errors::CLIError;
|
||||||
|
|
||||||
use clap::{App, AppSettings};
|
use clap::{App, AppSettings};
|
||||||
@ -135,9 +135,9 @@ fn main() -> Result<(), CLIError> {
|
|||||||
|
|
||||||
|
|
||||||
match arguments.subcommand() {
|
match arguments.subcommand() {
|
||||||
// ("init", Some(arguments)) => {
|
("init", Some(arguments)) => {
|
||||||
// NewCommand::().output(NewCommand::parse(arguments)?)
|
InitCommand::output(InitCommand::parse(arguments)?)
|
||||||
// },
|
},
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,5 @@
|
|||||||
use crate::errors::ManifestError;
|
use crate::errors::ManifestError;
|
||||||
|
|
||||||
use failure::Fail;
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
|
Loading…
Reference in New Issue
Block a user