diff --git a/examples/hello-world/src/main.leo b/examples/hello-world/src/main.leo
index 3574c43344..17d31d1e07 100644
--- a/examples/hello-world/src/main.leo
+++ b/examples/hello-world/src/main.leo
@@ -1,6 +1,9 @@
-function main(
- public r0: field,
- r1: field
-) -> field {
- return r0 + r1;
+record Token {
+ owner: address,
+ balance: u64,
+ token_amount: u64,
+}
+
+function main(r0: Token) -> u64 {
+ return r0.token_amount + r0.token_amount;
}
\ No newline at end of file
diff --git a/leo/commands/build.rs b/leo/commands/build.rs
index 44aad2e893..6105575632 100644
--- a/leo/commands/build.rs
+++ b/leo/commands/build.rs
@@ -21,7 +21,7 @@ use leo_package::{
inputs::InputFile,
// inputs::*,
// outputs::CircuitFile
- outputs::{ChecksumFile, OutputsDirectory, OUTPUTS_DIRECTORY_NAME},
+ outputs::{AleoFile, ChecksumFile, OutputsDirectory, OUTPUTS_DIRECTORY_NAME},
source::{MainFile, MAIN_FILENAME, SOURCE_DIRECTORY_NAME},
};
@@ -167,31 +167,22 @@ impl Command for Build {
let program_checksum = program.checksum()?;
// Compile the program.
- // TODO: Remove when code generation is ready to be integrated into the compiler.
- // match self.compiler_options.enable_code_generation {
- // false => {
- // program.compile()?;
- // }
- // true => {
+ {
+ let (_, bytecode) = program.compile_and_generate_bytecode()?;
+ // // Initialize AVM bytecode.
+ // Process::from_str(&bytecode);
+ //
+ // // Run program todo: run with real inputs.
+ // // Run the `HelloWorld` program with the given inputs.
+ // let first = Value::from_str("1field.public");
+ // let second = Value::from_str("1field.private");
+ // let output = Process::get_function(&Identifier::from_str("main")).unwrap().evaluate(&[first, second]);
+ // println!("program output: {}\n", output.first().unwrap());
- let (_, bytecode) = program.compile_and_generate_bytecode()?;
- // TODO: Remove when AVM output file format is stabilized.
- tracing::info!("Printing bytecode...\n");
- println!("{}", bytecode);
-
- // {
- // // Initialize AVM bytecode.
- // Process::from_str(&bytecode);
- //
- // // Run program todo: run with real inputs.
- // // Run the `HelloWorld` program with the given inputs.
- // let first = Value::from_str("1field.public");
- // let second = Value::from_str("1field.private");
- // let output = Process::get_function(&Identifier::from_str("main")).unwrap().evaluate(&[first, second]);
- // println!("program output: {}\n", output.first().unwrap());
- // }
- // }
- // }
+ // Write the Aleo file to the output directory.
+ let aleo_file = AleoFile::new(&package_name);
+ aleo_file.write_to(&path, bytecode)?;
+ }
// Generate the program on the constraint system and verify correctness
{
diff --git a/leo/commands/unused/clean.rs b/leo/commands/clean.rs
similarity index 85%
rename from leo/commands/unused/clean.rs
rename to leo/commands/clean.rs
index 6d70d906c2..80cfe8e90c 100644
--- a/leo/commands/unused/clean.rs
+++ b/leo/commands/clean.rs
@@ -15,18 +15,14 @@
// along with the Leo library. If not, see .
use crate::{commands::Command, context::Context};
-use leo_compiler::OutputFile;
use leo_errors::Result;
-use leo_package::outputs::{
- ChecksumFile, CircuitFile, ProofFile, ProvingKeyFile, Snapshot, SnapshotFile, VerificationKeyFile,
-};
+use leo_package::outputs::{AleoFile, ChecksumFile, CircuitFile, ProofFile, ProvingKeyFile, Snapshot, SnapshotFile, VerificationKeyFile};
-use structopt::StructOpt;
+use clap::StructOpt;
use tracing::span::Span;
/// Clean outputs folder command
#[derive(StructOpt, Debug)]
-#[structopt(setting = structopt::clap::AppSettings::ColoredHelp)]
pub struct Clean {}
impl Command for Clean {
@@ -45,14 +41,17 @@ impl Command for Clean {
let path = context.dir()?;
let package_name = context.manifest()?.get_package_name();
+ // Remove the aleo file from the output directory.
+ AleoFile::new(&package_name).remove(&path)?;
+
// Remove the checksum from the output directory
ChecksumFile::new(&package_name).remove(&path)?;
// Remove the serialized circuit from the output directory
CircuitFile::new(&package_name).remove(&path)?;
- // Remove the program output file from the output directory
- OutputFile::new(&package_name).remove(&path)?;
+ // // Remove the program output file from the output directory
+ // OutputFile::new(&package_name).remove(&path)?;
// Remove the proving key from the output directory
ProvingKeyFile::new(&package_name).remove(&path)?;
diff --git a/leo/commands/mod.rs b/leo/commands/mod.rs
index cd3a47eb52..b473354c32 100644
--- a/leo/commands/mod.rs
+++ b/leo/commands/mod.rs
@@ -23,9 +23,9 @@ use tracing::span::Span;
// local program commands
pub mod build;
pub use build::Build;
-//
-// pub mod clean;
-// pub use clean::Clean;
+
+pub mod clean;
+pub use clean::Clean;
//
// pub mod deploy;
// pub use deploy::Deploy;
diff --git a/leo/errors/src/errors/package/package_errors.rs b/leo/errors/src/errors/package/package_errors.rs
index b971c71f79..4fcc457583 100644
--- a/leo/errors/src/errors/package/package_errors.rs
+++ b/leo/errors/src/errors/package/package_errors.rs
@@ -21,8 +21,6 @@ use std::{
fmt::{Debug, Display},
};
-// todo (collin): redo these after Mazdak finishes error indexing.
-
create_messages!(
/// PackageError enum that represents all the errors for the `leo-package` crate.
PackageError,
@@ -134,6 +132,14 @@ create_messages!(
help: None,
}
+ /// For when reading the aleo file failed.
+ @backtraced
+ failed_to_read_aleo_file {
+ args: (path: impl Debug),
+ msg: format!("Cannot read aleo file from the provided file path - {:?}", path),
+ help: None,
+ }
+
/// For when reading the checksum file failed.
@backtraced
failed_to_read_checksum_file {
@@ -303,6 +309,22 @@ create_messages!(
help: None,
}
+ /// For when the aleo file has an IO error.
+ @backtraced
+ io_error_aleo_file {
+ args: (error: impl ErrorArg),
+ msg: format!("IO error aleo file from the provided file path - {}", error),
+ help: None,
+ }
+
+ /// For when removing the circuit file failed.
+ @backtraced
+ failed_to_remove_aleo_file {
+ args: (path: impl Debug),
+ msg: format!("failed removing aleo file from the provided file path - {:?}", path),
+ help: None,
+ }
+
/// For when removing the circuit file failed.
@backtraced
failed_to_remove_circuit_file {
diff --git a/leo/main.rs b/leo/main.rs
index 9be6e49430..7705019fa8 100644
--- a/leo/main.rs
+++ b/leo/main.rs
@@ -24,7 +24,7 @@ pub mod updater;
use commands::{
// package::{Clone, Fetch, Login, Logout, Publish},
Build,
- // Clean,
+ Clean,
Command,
// Deploy, Init, Lint, New, Prove, Run, Setup, Test, Update, Watch,
};
@@ -79,6 +79,12 @@ enum CommandOpts {
#[structopt(flatten)]
command: Build,
},
+ #[structopt(about = "Clean the output directory")]
+ Clean {
+ #[structopt(flatten)]
+ command: Clean,
+ },
+
//
// #[structopt(about = "Run a program setup")]
// Setup {
@@ -98,12 +104,6 @@ enum CommandOpts {
// command: Run,
// },
//
- // #[structopt(about = "Clean the output directory")]
- // Clean {
- // #[structopt(flatten)]
- // command: Clean,
- // },
- //
// #[structopt(about = "Watch for changes of Leo source files")]
// Watch {
// #[structopt(flatten)]
@@ -233,11 +233,11 @@ fn run_with_args(opt: Opt) -> Result<()> {
// CommandOpts::Init { command } => command.try_execute(context),
// CommandOpts::New { command } => command.try_execute(context),
CommandOpts::Build { command } => command.try_execute(context),
+ CommandOpts::Clean { 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),
//
diff --git a/leo/package/src/outputs/aleo.rs b/leo/package/src/outputs/aleo.rs
new file mode 100644
index 0000000000..5767734467
--- /dev/null
+++ b/leo/package/src/outputs/aleo.rs
@@ -0,0 +1,97 @@
+// Copyright (C) 2019-2022 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 .
+
+//! An Aleo file.
+
+use crate::outputs::OUTPUTS_DIRECTORY_NAME;
+use leo_errors::{PackageError, Result};
+
+use serde::Deserialize;
+use std::{
+ borrow::Cow,
+ fs::{
+ File, {self},
+ },
+ io::Write,
+ path::Path,
+};
+
+pub static CHECKSUM_FILE_EXTENSION: &str = ".aleo";
+
+#[derive(Deserialize)]
+pub struct AleoFile {
+ pub package_name: String,
+}
+
+impl AleoFile {
+ pub fn new(package_name: &str) -> Self {
+ Self {
+ package_name: package_name.to_string(),
+ }
+ }
+
+ pub fn exists_at(&self, path: &Path) -> bool {
+ let path = self.setup_file_path(path);
+ path.exists()
+ }
+
+ /// Reads the aleo from the given file path if it exists.
+ pub fn read_from(&self, path: &Path) -> Result {
+ let path = self.setup_file_path(path);
+
+ let string =
+ fs::read_to_string(&path).map_err(|_| PackageError::failed_to_read_aleo_file(path.into_owned()))?;
+ Ok(string)
+ }
+
+ /// Writes the given aleo to a file.
+ pub fn write_to(&self, path: &Path, aleo: String) -> Result<()> {
+ let path = self.setup_file_path(path);
+ let mut file = File::create(&path).map_err(PackageError::io_error_aleo_file)?;
+
+ // Write program id to file.
+ let mut aleo_file = format!("program {};\n\n", self.package_name);
+ aleo_file.push_str(&aleo);
+
+ file.write_all(aleo_file.as_bytes())
+ .map_err(PackageError::io_error_aleo_file)?;
+ Ok(())
+ }
+
+ /// Removes the aleo file at the given path if it exists. Returns `true` on success,
+ /// `false` if the file doesn't exist, and `Error` if the file system fails during operation.
+ pub fn remove(&self, path: &Path) -> Result {
+ let path = self.setup_file_path(path);
+ if !path.exists() {
+ return Ok(false);
+ }
+
+ fs::remove_file(&path).map_err(|_| PackageError::failed_to_remove_aleo_file(path.into_owned()))?;
+ Ok(true)
+ }
+
+ fn setup_file_path<'a>(&self, path: &'a Path) -> Cow<'a, Path> {
+ let mut path = Cow::from(path);
+ if path.is_dir() {
+ if !path.ends_with(OUTPUTS_DIRECTORY_NAME) {
+ path.to_mut().push(OUTPUTS_DIRECTORY_NAME);
+ }
+ path.to_mut()
+ .push(format!("{}{}", self.package_name, CHECKSUM_FILE_EXTENSION));
+ }
+ path
+ }
+}
diff --git a/leo/package/src/outputs/mod.rs b/leo/package/src/outputs/mod.rs
index 9268adb8f0..07a341d1a9 100644
--- a/leo/package/src/outputs/mod.rs
+++ b/leo/package/src/outputs/mod.rs
@@ -13,6 +13,8 @@
// You should have received a copy of the GNU General Public License
// along with the Leo library. If not, see .
+pub mod aleo;
+pub use self::aleo::*;
pub mod ast_snapshot;
pub use self::ast_snapshot::*;