adds --path argument to Leo command

- also features small change in architecture - context is now created in main
This commit is contained in:
damirka 2021-03-30 11:43:44 +03:00
parent f6e602347a
commit b80cc62368
20 changed files with 61 additions and 58 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -33,7 +33,7 @@ impl Command for Lint {
tracing::span!(tracing::Level::INFO, "Linting") tracing::span!(tracing::Level::INFO, "Linting")
} }
fn prelude(&self) -> Result<Self::Input> { fn prelude(&self, _: Context) -> Result<Self::Input> {
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::context::{get_context, Context}; use crate::context::Context;
use anyhow::Result; use anyhow::Result;
use std::time::Instant; use std::time::Instant;
@ -72,11 +72,6 @@ pub trait Command {
/// this field may be left empty. /// this field may be left empty.
type Output; 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`. /// Adds a span to the logger via `tracing::span`.
/// Because of the specifics of the macro implementation, it is not possible /// 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 /// 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. /// 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 where
Self: std::marker::Sized; Self: std::marker::Sized;
@ -98,11 +93,11 @@ pub trait Command {
/// A wrapper around the `apply` method. /// A wrapper around the `apply` method.
/// This function sets up tracing, timing, and the context. /// This function sets up tracing, timing, and the context.
fn execute(self) -> Result<Self::Output> fn execute(self, context: Context) -> Result<Self::Output>
where where
Self: std::marker::Sized, Self: std::marker::Sized,
{ {
let input = self.prelude()?; let input = self.prelude(context.clone())?;
// Create the span for this command. // Create the span for this command.
let span = self.log_span(); let span = self.log_span();
@ -110,8 +105,6 @@ pub trait Command {
// Calculate the execution time for this command. // Calculate the execution time for this command.
let timer = Instant::now(); let timer = Instant::now();
let context = self.context()?;
let out = self.apply(context, input); let out = self.apply(context, input);
drop(span); drop(span);
@ -127,10 +120,10 @@ pub trait Command {
/// Executes command but empty the result. Comes in handy where there's a /// Executes command but empty the result. Comes in handy where there's a
/// need to make match arms compatible while keeping implementation-specific /// need to make match arms compatible while keeping implementation-specific
/// output possible. Errors however are all of the type Error /// output possible. Errors however are all of the type Error
fn try_execute(self) -> Result<()> fn try_execute(self, context: Context) -> Result<()>
where where
Self: std::marker::Sized, 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") tracing::span!(tracing::Level::INFO, "New")
} }
fn prelude(&self) -> Result<Self::Input> { fn prelude(&self, _: Context) -> Result<Self::Input> {
Ok(()) Ok(())
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -46,8 +46,8 @@ impl Command for Publish {
type Output = Option<String>; type Output = Option<String>;
/// Build program before publishing /// Build program before publishing
fn prelude(&self) -> Result<Self::Input> { fn prelude(&self, context: Context) -> Result<Self::Input> {
(Build {}).execute() (Build {}).execute(context)
} }
fn apply(self, context: Context, _input: Self::Input) -> Result<Self::Output> { 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") tracing::span!(tracing::Level::INFO, "Removing")
} }
fn prelude(&self) -> Result<Self::Input> { fn prelude(&self, _: Context) -> Result<Self::Input> {
Ok(()) Ok(())
} }

View File

@ -45,9 +45,9 @@ impl Command for Prove {
tracing::span!(tracing::Level::INFO, "Proving") 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; 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> { 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") 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; 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> { 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") tracing::span!(tracing::Level::INFO, "Setup")
} }
fn prelude(&self) -> Result<Self::Input> { fn prelude(&self, context: Context) -> Result<Self::Input> {
(Build {}).execute() (Build {}).execute(context)
} }
fn apply(self, context: Context, input: Self::Input) -> Result<Self::Output> { 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") tracing::span!(tracing::Level::INFO, "Test")
} }
fn prelude(&self) -> Result<Self::Input> { fn prelude(&self, _: Context) -> Result<Self::Input> {
Ok(()) Ok(())
} }

View File

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

View File

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

View File

@ -39,7 +39,7 @@ use commands::{
}; };
use anyhow::Error; use anyhow::Error;
use std::process::exit; use std::{path::PathBuf, process::exit};
use structopt::{clap::AppSettings, StructOpt}; use structopt::{clap::AppSettings, StructOpt};
/// CLI Arguments entry point - includes global parameters and subcommands /// CLI Arguments entry point - includes global parameters and subcommands
@ -54,6 +54,9 @@ struct Opt {
#[structopt(subcommand)] #[structopt(subcommand)]
command: CommandOpts, command: CommandOpts,
#[structopt(short, long, help = "Optional path to Leo program root folder", parse(from_os_str))]
path: Option<PathBuf>,
} }
///Leo compiler and package manager ///Leo compiler and package manager
@ -170,38 +173,45 @@ enum CommandOpts {
} }
fn main() { fn main() {
// read command line arguments // Read command line arguments.
let opt = Opt::from_args(); let opt = Opt::from_args();
if !opt.quiet { if !opt.quiet {
// init logger with optional debug flag // Init logger with optional debug flag.
logger::init_logger("leo", match opt.debug { logger::init_logger("leo", match opt.debug {
false => 1, false => 1,
true => 2, 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 { handle_error(match opt.command {
CommandOpts::Init { command } => command.try_execute(), CommandOpts::Init { command } => command.try_execute(context),
CommandOpts::New { command } => command.try_execute(), CommandOpts::New { command } => command.try_execute(context),
CommandOpts::Build { command } => command.try_execute(), CommandOpts::Build { command } => command.try_execute(context),
CommandOpts::Setup { command } => command.try_execute(), CommandOpts::Setup { command } => command.try_execute(context),
CommandOpts::Prove { command } => command.try_execute(), CommandOpts::Prove { command } => command.try_execute(context),
CommandOpts::Test { command } => command.try_execute(), CommandOpts::Test { command } => command.try_execute(context),
CommandOpts::Run { command } => command.try_execute(), CommandOpts::Run { command } => command.try_execute(context),
CommandOpts::Clean { command } => command.try_execute(), CommandOpts::Clean { command } => command.try_execute(context),
CommandOpts::Watch { command } => command.try_execute(), CommandOpts::Watch { command } => command.try_execute(context),
CommandOpts::Update { command } => command.try_execute(), CommandOpts::Update { command } => command.try_execute(context),
CommandOpts::Add { command } => command.try_execute(), CommandOpts::Add { command } => command.try_execute(context),
CommandOpts::Clone { command } => command.try_execute(), CommandOpts::Clone { command } => command.try_execute(context),
CommandOpts::Login { command } => command.try_execute(), CommandOpts::Login { command } => command.try_execute(context),
CommandOpts::Logout { command } => command.try_execute(), CommandOpts::Logout { command } => command.try_execute(context),
CommandOpts::Publish { command } => command.try_execute(), CommandOpts::Publish { command } => command.try_execute(context),
CommandOpts::Remove { command } => command.try_execute(), CommandOpts::Remove { command } => command.try_execute(context),
CommandOpts::Lint { command } => command.try_execute(), CommandOpts::Lint { command } => command.try_execute(context),
CommandOpts::Deploy { command } => command.try_execute(), CommandOpts::Deploy { command } => command.try_execute(context),
}); });
} }