Merge pull request #814 from AleoHQ/feature/leo-path-cli

[CLI] Adds --path argument to Leo CLI
This commit is contained in:
Collin Chin 2021-04-08 13:07:06 -07:00 committed by GitHub
commit 3b76a2dfd8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 73 additions and 64 deletions

View File

@ -1,6 +1,6 @@
# leo add (w/o login) & remove
$LEO new my-app && cd my-app
$LEO new my-app && cd my-app || exit 1
$LEO add howard/silly-sudoku
$LEO remove silly-sudoku
$LEO clean

View File

@ -1,4 +1,5 @@
mkdir hello-world && cd hello-world || exit 1
$LEO init
ls -la
mkdir hello-world
cd hello-world
$LEO init || exit 1
ls -la hello-world
$LEO run

View File

@ -45,7 +45,7 @@ impl Command for Build {
tracing::span!(tracing::Level::INFO, "Build")
}
fn prelude(&self) -> Result<Self::Input> {
fn prelude(&self, _: Context) -> Result<Self::Input> {
Ok(())
}

View File

@ -35,7 +35,7 @@ impl Command for Clean {
tracing::span!(tracing::Level::INFO, "Cleaning")
}
fn prelude(&self) -> Result<Self::Input> {
fn prelude(&self, _: Context) -> Result<Self::Input> {
Ok(())
}

View File

@ -33,7 +33,7 @@ impl Command for Deploy {
tracing::span!(tracing::Level::INFO, "Deploy")
}
fn prelude(&self) -> Result<Self::Input> {
fn prelude(&self, _: Context) -> Result<Self::Input> {
Ok(())
}

View File

@ -35,7 +35,7 @@ impl Command for Init {
tracing::span!(tracing::Level::INFO, "Initializing")
}
fn prelude(&self) -> Result<Self::Input> {
fn prelude(&self, _: Context) -> Result<Self::Input> {
Ok(())
}

View File

@ -33,7 +33,7 @@ impl Command for Lint {
tracing::span!(tracing::Level::INFO, "Linting")
}
fn prelude(&self) -> Result<Self::Input> {
fn prelude(&self, _: Context) -> Result<Self::Input> {
Ok(())
}

View File

@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::context::{get_context, Context};
use crate::context::Context;
use anyhow::Result;
use std::time::Instant;
@ -72,11 +72,6 @@ pub trait Command {
/// this field may be left empty.
type Output;
/// Returns the project context, which is defined as the current directory.
fn context(&self) -> Result<Context> {
get_context()
}
/// Adds a span to the logger via `tracing::span`.
/// Because of the specifics of the macro implementation, it is not possible
/// to set the span name with a non-literal i.e. a dynamic variable even if this
@ -86,7 +81,7 @@ pub trait Command {
}
/// Runs the prelude and returns the Input of the current command.
fn prelude(&self) -> Result<Self::Input>
fn prelude(&self, context: Context) -> Result<Self::Input>
where
Self: std::marker::Sized;
@ -98,11 +93,11 @@ pub trait Command {
/// A wrapper around the `apply` method.
/// This function sets up tracing, timing, and the context.
fn execute(self) -> Result<Self::Output>
fn execute(self, context: Context) -> Result<Self::Output>
where
Self: std::marker::Sized,
{
let input = self.prelude()?;
let input = self.prelude(context.clone())?;
// Create the span for this command.
let span = self.log_span();
@ -110,8 +105,6 @@ pub trait Command {
// Calculate the execution time for this command.
let timer = Instant::now();
let context = self.context()?;
let out = self.apply(context, input);
drop(span);
@ -127,10 +120,10 @@ pub trait Command {
/// Executes command but empty the result. Comes in handy where there's a
/// need to make match arms compatible while keeping implementation-specific
/// output possible. Errors however are all of the type Error
fn try_execute(self) -> Result<()>
fn try_execute(self, context: Context) -> Result<()>
where
Self: std::marker::Sized,
{
self.execute().map(|_| Ok(()))?
self.execute(context).map(|_| Ok(()))?
}
}

View File

@ -38,7 +38,7 @@ impl Command for New {
tracing::span!(tracing::Level::INFO, "New")
}
fn prelude(&self) -> Result<Self::Input> {
fn prelude(&self, _: Context) -> Result<Self::Input> {
Ok(())
}

View File

@ -86,7 +86,7 @@ impl Command for Add {
tracing::span!(tracing::Level::INFO, "Adding")
}
fn prelude(&self) -> Result<Self::Input> {
fn prelude(&self, _: Context) -> Result<Self::Input> {
Ok(())
}

View File

@ -103,7 +103,7 @@ impl Command for Clone {
tracing::span!(tracing::Level::INFO, "Cloning")
}
fn prelude(&self) -> Result<Self::Input> {
fn prelude(&self, _: Context) -> Result<Self::Input> {
Ok(())
}

View File

@ -54,7 +54,7 @@ impl Command for Login {
tracing::span!(tracing::Level::INFO, "Login")
}
fn prelude(&self) -> Result<Self::Input> {
fn prelude(&self, _: Context) -> Result<Self::Input> {
Ok(())
}

View File

@ -34,7 +34,7 @@ impl Command for Logout {
tracing::span!(tracing::Level::INFO, "Logout")
}
fn prelude(&self) -> Result<Self::Input> {
fn prelude(&self, _: Context) -> Result<Self::Input> {
Ok(())
}

View File

@ -46,8 +46,8 @@ impl Command for Publish {
type Output = Option<String>;
/// Build program before publishing
fn prelude(&self) -> Result<Self::Input> {
(Build {}).execute()
fn prelude(&self, context: Context) -> Result<Self::Input> {
(Build {}).execute(context)
}
fn apply(self, context: Context, _input: Self::Input) -> Result<Self::Output> {

View File

@ -37,7 +37,7 @@ impl Command for Remove {
tracing::span!(tracing::Level::INFO, "Removing")
}
fn prelude(&self) -> Result<Self::Input> {
fn prelude(&self, _: Context) -> Result<Self::Input> {
Ok(())
}

View File

@ -45,9 +45,9 @@ impl Command for Prove {
tracing::span!(tracing::Level::INFO, "Proving")
}
fn prelude(&self) -> Result<Self::Input> {
fn prelude(&self, context: Context) -> Result<Self::Input> {
let skip_key_check = self.skip_key_check;
(Setup { skip_key_check }).execute()
(Setup { skip_key_check }).execute(context)
}
fn apply(self, context: Context, input: Self::Input) -> Result<Self::Output> {

View File

@ -40,9 +40,9 @@ impl Command for Run {
tracing::span!(tracing::Level::INFO, "Verifying")
}
fn prelude(&self) -> Result<Self::Input> {
fn prelude(&self, context: Context) -> Result<Self::Input> {
let skip_key_check = self.skip_key_check;
(Prove { skip_key_check }).execute()
(Prove { skip_key_check }).execute(context)
}
fn apply(self, _context: Context, input: Self::Input) -> Result<Self::Output> {

View File

@ -49,8 +49,8 @@ impl Command for Setup {
tracing::span!(tracing::Level::INFO, "Setup")
}
fn prelude(&self) -> Result<Self::Input> {
(Build {}).execute()
fn prelude(&self, context: Context) -> Result<Self::Input> {
(Build {}).execute(context)
}
fn apply(self, context: Context, input: Self::Input) -> Result<Self::Output> {

View File

@ -47,7 +47,7 @@ impl Command for Test {
tracing::span!(tracing::Level::INFO, "Test")
}
fn prelude(&self) -> Result<Self::Input> {
fn prelude(&self, _: Context) -> Result<Self::Input> {
Ok(())
}

View File

@ -54,7 +54,7 @@ impl Command for Update {
tracing::span!(tracing::Level::INFO, "Updating")
}
fn prelude(&self) -> Result<Self::Input> {
fn prelude(&self, _: Context) -> Result<Self::Input> {
Ok(())
}

View File

@ -43,11 +43,11 @@ impl Command for Watch {
tracing::span!(tracing::Level::INFO, "Watching")
}
fn prelude(&self) -> Result<Self::Input> {
fn prelude(&self, _: Context) -> Result<Self::Input> {
Ok(())
}
fn apply(self, _context: Context, _: Self::Input) -> Result<Self::Output> {
fn apply(self, context: Context, _: Self::Input) -> Result<Self::Output> {
let (tx, rx) = channel();
let mut watcher = watcher(tx, Duration::from_secs(self.interval)).unwrap();
@ -64,7 +64,7 @@ impl Command for Watch {
match rx.recv() {
// See changes on the write event
Ok(DebouncedEvent::Write(_write)) => {
match (Build {}).execute() {
match (Build {}).execute(context.clone()) {
Ok(_output) => {
tracing::info!("Built successfully");
}

View File

@ -39,21 +39,29 @@ use commands::{
};
use anyhow::Error;
use std::process::exit;
use std::{path::PathBuf, process::exit};
use structopt::{clap::AppSettings, StructOpt};
/// CLI Arguments entry point - includes global parameters and subcommands
#[derive(StructOpt, Debug)]
#[structopt(name = "leo", author = "The Aleo Team <hello@aleo.org>", setting = AppSettings::ColoredHelp)]
struct Opt {
#[structopt(short, long, help = "Print additional information for debugging")]
#[structopt(short, global = true, help = "Print additional information for debugging")]
debug: bool,
#[structopt(short, long, help = "Suppress CLI output")]
#[structopt(short, global = true, help = "Suppress CLI output")]
quiet: bool,
#[structopt(subcommand)]
command: CommandOpts,
#[structopt(
long,
global = true,
help = "Optional path to Leo program root folder",
parse(from_os_str)
)]
path: Option<PathBuf>,
}
///Leo compiler and package manager
@ -170,38 +178,45 @@ enum CommandOpts {
}
fn main() {
// read command line arguments
// Read command line arguments.
let opt = Opt::from_args();
if !opt.quiet {
// init logger with optional debug flag
// Init logger with optional debug flag.
logger::init_logger("leo", match opt.debug {
false => 1,
true => 2,
});
}
// Get custom root folder and create context for it.
// If not specified, default context will be created in cwd.
let context = handle_error(match opt.path {
Some(path) => context::create_context(path),
None => context::get_context(),
});
handle_error(match opt.command {
CommandOpts::Init { command } => command.try_execute(),
CommandOpts::New { command } => command.try_execute(),
CommandOpts::Build { command } => command.try_execute(),
CommandOpts::Setup { command } => command.try_execute(),
CommandOpts::Prove { command } => command.try_execute(),
CommandOpts::Test { command } => command.try_execute(),
CommandOpts::Run { command } => command.try_execute(),
CommandOpts::Clean { command } => command.try_execute(),
CommandOpts::Watch { command } => command.try_execute(),
CommandOpts::Update { command } => command.try_execute(),
CommandOpts::Init { command } => command.try_execute(context),
CommandOpts::New { command } => command.try_execute(context),
CommandOpts::Build { command } => command.try_execute(context),
CommandOpts::Setup { command } => command.try_execute(context),
CommandOpts::Prove { command } => command.try_execute(context),
CommandOpts::Test { command } => command.try_execute(context),
CommandOpts::Run { command } => command.try_execute(context),
CommandOpts::Clean { command } => command.try_execute(context),
CommandOpts::Watch { command } => command.try_execute(context),
CommandOpts::Update { command } => command.try_execute(context),
CommandOpts::Add { command } => command.try_execute(),
CommandOpts::Clone { command } => command.try_execute(),
CommandOpts::Login { command } => command.try_execute(),
CommandOpts::Logout { command } => command.try_execute(),
CommandOpts::Publish { command } => command.try_execute(),
CommandOpts::Remove { command } => command.try_execute(),
CommandOpts::Add { command } => command.try_execute(context),
CommandOpts::Clone { command } => command.try_execute(context),
CommandOpts::Login { command } => command.try_execute(context),
CommandOpts::Logout { command } => command.try_execute(context),
CommandOpts::Publish { command } => command.try_execute(context),
CommandOpts::Remove { command } => command.try_execute(context),
CommandOpts::Lint { command } => command.try_execute(),
CommandOpts::Deploy { command } => command.try_execute(),
CommandOpts::Lint { command } => command.try_execute(context),
CommandOpts::Deploy { command } => command.try_execute(context),
});
}