Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement leo example command for lottery, tictactoe, token #2514

Merged
merged 5 commits into from
Aug 8, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions errors/src/errors/cli/cli_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,4 +164,11 @@ create_messages!(
msg: format!("Failed to execute the `execute` command.\nSnarkVM Error: {error}"),
help: None,
}

@backtraced
failed_to_write_file {
args: (error: impl Display),
msg: format!("Failed to write file.\nIO Error: {error}"),
help: None,
}
);
9 changes: 6 additions & 3 deletions leo/cli/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@ pub struct CLI {
#[clap(subcommand)]
command: Commands,

#[clap(help = "Custom Aleo PM backend URL", env = "APM_URL")]
api: Option<String>,

#[clap(long, global = true, help = "Optional path to Leo program root folder")]
path: Option<PathBuf>,
}
Expand All @@ -50,6 +47,11 @@ enum Commands {
// command: Init,
// },
//
#[clap(about = "Create a new Leo example package in a new directory")]
Example {
#[clap(subcommand)]
command: Example,
},
#[clap(about = "Create a new Leo package in a new directory")]
New {
#[clap(flatten)]
Expand Down Expand Up @@ -132,6 +134,7 @@ pub fn run_with_args(cli: CLI) -> Result<()> {
command.try_execute(context)
}
Commands::Clean { command } => command.try_execute(context),
Commands::Example { command } => command.try_execute(context),
Commands::Run { command } => command.try_execute(context),
Commands::Execute { command } => command.try_execute(context),
Commands::Update { command } => command.try_execute(context),
Expand Down
102 changes: 102 additions & 0 deletions leo/cli/commands/example.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Copyright (C) 2019-2023 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 <https://www.gnu.org/licenses/>.

use super::*;

use std::fs;

/// The example programs that can be generated.
#[derive(Parser, Debug)]
pub enum Example {
#[clap(name = "lottery", about = "A public lottery program")]
Lottery,
#[clap(name = "tictactoe", about = "A standard tic-tac-toe game program")]
TicTacToe,
#[clap(name = "token", about = "A transparent & shielded custom token program")]
Token,
}

impl Command for Example {
type Input = <New as Command>::Output;
type Output = ();

fn prelude(&self, context: Context) -> Result<Self::Input> {
// Run leo new EXAMPLE_NAME
(New { name: self.name() }).execute(context)
}

fn apply(self, context: Context, _: Self::Input) -> Result<Self::Output>
where
Self: Sized,
{
let package_dir = context.dir()?;

// Write the main file.
let main_file_path = package_dir.join("src").join("main.leo");
fs::write(main_file_path, self.main_file_string()).map_err(CliError::failed_to_write_file)?;

// Write the input file.
let input_file_path = package_dir.join("inputs").join("input.in");
fs::write(input_file_path, self.input_file_string()).map_err(CliError::failed_to_write_file)?;

// Write the README file.
let readme_file_path = package_dir.join("README.md");
let readme_file_path_string = readme_file_path.display().to_string();
fs::write(readme_file_path, self.readme_file_string()).map_err(CliError::failed_to_write_file)?;

tracing::info!(
"🚀 To run the '{}' program follow the instructions at {}",
self.name().bold(),
readme_file_path_string
);

Ok(())
}
}

impl Example {
fn name(&self) -> String {
match self {
Example::Lottery => "lottery".to_string(),
Example::TicTacToe => "tictactoe".to_string(),
Example::Token => "token".to_string(),
}
}

fn main_file_string(&self) -> String {
match self {
Self::Lottery => include_str!("../../../examples/lottery/src/main.leo").to_string(),
Self::TicTacToe => include_str!("../../../examples/tictactoe/src/main.leo").to_string(),
Self::Token => include_str!("../../../examples/token/src/main.leo").to_string(),
}
}

fn input_file_string(&self) -> String {
match self {
Self::Lottery => include_str!("../../../examples/lottery/inputs/lottery.in").to_string(),
Self::TicTacToe => include_str!("../../../examples/tictactoe/inputs/tictactoe.in").to_string(),
Self::Token => include_str!("../../../examples/token/inputs/token.in").to_string(),
}
}

fn readme_file_string(&self) -> String {
match self {
Self::Lottery => include_str!("../../../examples/lottery/README.md").to_string(),
Self::TicTacToe => include_str!("../../../examples/tictactoe/README.md").to_string(),
Self::Token => include_str!("../../../examples/token/README.md").to_string(),
}
}
}
3 changes: 3 additions & 0 deletions leo/cli/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ pub use build::Build;
pub mod clean;
pub use clean::Clean;

pub mod example;
pub use example::Example;

pub mod execute;
pub use execute::Execute;

Expand Down
4 changes: 1 addition & 3 deletions leo/cli/commands/new.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use snarkvm::{cli::New as SnarkVMNew, file::AleoFile};
#[derive(Parser, Debug)]
pub struct New {
#[clap(name = "NAME", help = "Set package name")]
name: String,
pub(crate) name: String,
}

impl Command for New {
Expand All @@ -43,8 +43,6 @@ impl Command for New {
SnarkVMNew::try_parse_from([SNARKVM_COMMAND, &self.name]).map_err(CliError::failed_to_parse_new)?;
let result = command.parse().map_err(CliError::failed_to_execute_new)?;

// todo: modify the readme file to recommend building with `leo build`.

// Log the output of the `aleo new` command.
tracing::info!("{}", result);

Expand Down
42 changes: 42 additions & 0 deletions leo/package/src/example.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (C) 2019-2023 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 <https://www.gnu.org/licenses/>.

use super::*;

/// The example programs that can be generated.
pub enum Example {
Lottery,
TicTacToe,
Token,
}

impl Example {
pub fn main_file_string(&self, package_name: &str) -> String {
match self {
Self::Lottery => include_str!("../../examples/lottery/src/main.leo").to_string(),
Self::TicTacToe => include_str!("../../examples/tic_tac_toe/src/main.leo").to_string(),
Self::Token => include_str!("../../examples/token/src/main.leo").to_string(),
}
}

pub fn input_file_string(&self, package_name: &str) -> String {
match self {
Self::Lottery => include_str!("../../examples/lottery/inputs/input.in").to_string(),
Self::TicTacToe => include_str!("../../examples/tic_tac_toe/inputs/input.in").to_string(),
Self::Token => include_str!("../../examples/token/inputs/input.in").to_string(),
}
}
}
Loading