mirror of
https://github.com/AleoHQ/leo.git
synced 2024-09-22 04:27:25 +03:00
Merge pull request #883 from AleoHQ/feature-cli-coverage
[CLI] Adds integration tests to Leo CLI + removes --lib legacy
This commit is contained in:
commit
35619c99b4
161
Cargo.lock
generated
161
Cargo.lock
generated
@ -87,6 +87,20 @@ version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
||||
|
||||
[[package]]
|
||||
name = "assert_cmd"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2475b58cd94eb4f70159f4fd8844ba3b807532fe3131b3373fae060bbe30396"
|
||||
dependencies = [
|
||||
"bstr",
|
||||
"doc-comment",
|
||||
"predicates",
|
||||
"predicates-core",
|
||||
"predicates-tree",
|
||||
"wait-timeout",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
@ -601,6 +615,12 @@ dependencies = [
|
||||
"syn 1.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "difference"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.8.1"
|
||||
@ -639,6 +659,12 @@ dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "doc-comment"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
|
||||
|
||||
[[package]]
|
||||
name = "dtoa"
|
||||
version = "0.4.8"
|
||||
@ -1307,8 +1333,8 @@ dependencies = [
|
||||
"leo-state",
|
||||
"num-bigint",
|
||||
"pest",
|
||||
"rand",
|
||||
"rand_core",
|
||||
"rand 0.8.3",
|
||||
"rand_core 0.6.2",
|
||||
"rand_xorshift",
|
||||
"serde",
|
||||
"sha2",
|
||||
@ -1355,6 +1381,7 @@ version = "1.4.0"
|
||||
dependencies = [
|
||||
"ansi_term 0.12.1",
|
||||
"anyhow",
|
||||
"assert_cmd",
|
||||
"clap",
|
||||
"colored",
|
||||
"console",
|
||||
@ -1369,8 +1396,8 @@ dependencies = [
|
||||
"leo-state",
|
||||
"leo-synthesizer",
|
||||
"notify",
|
||||
"rand",
|
||||
"rand_core",
|
||||
"rand 0.8.3",
|
||||
"rand_core 0.6.2",
|
||||
"reqwest",
|
||||
"rusty-hook",
|
||||
"self_update",
|
||||
@ -1382,6 +1409,7 @@ dependencies = [
|
||||
"snarkvm-r1cs",
|
||||
"snarkvm-utilities",
|
||||
"structopt",
|
||||
"test_dir",
|
||||
"thiserror",
|
||||
"toml",
|
||||
"tracing",
|
||||
@ -1430,8 +1458,8 @@ dependencies = [
|
||||
"indexmap",
|
||||
"leo-ast",
|
||||
"leo-input",
|
||||
"rand",
|
||||
"rand_core",
|
||||
"rand 0.8.3",
|
||||
"rand_core 0.6.2",
|
||||
"rand_xorshift",
|
||||
"snarkvm-algorithms",
|
||||
"snarkvm-curves",
|
||||
@ -2048,6 +2076,32 @@ version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
|
||||
|
||||
[[package]]
|
||||
name = "predicates"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eeb433456c1a57cc93554dea3ce40b4c19c4057e41c55d4a0f3d84ea71c325aa"
|
||||
dependencies = [
|
||||
"difference",
|
||||
"predicates-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "predicates-core"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57e35a3326b75e49aa85f5dc6ec15b41108cf5aee58eabb1f274dd18b73c2451"
|
||||
|
||||
[[package]]
|
||||
name = "predicates-tree"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15f553275e5721409451eb85e15fd9a860a6e5ab4496eb215987502b5f5391f2"
|
||||
dependencies = [
|
||||
"predicates-core",
|
||||
"treeline",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-crate"
|
||||
version = "0.1.5"
|
||||
@ -2138,6 +2192,19 @@ version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
|
||||
dependencies = [
|
||||
"getrandom 0.1.16",
|
||||
"libc",
|
||||
"rand_chacha 0.2.2",
|
||||
"rand_core 0.5.1",
|
||||
"rand_hc 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.3"
|
||||
@ -2145,9 +2212,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
"rand_hc",
|
||||
"rand_chacha 0.3.0",
|
||||
"rand_core 0.6.2",
|
||||
"rand_hc 0.3.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core 0.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2157,7 +2234,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
"rand_core 0.6.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
||||
dependencies = [
|
||||
"getrandom 0.1.16",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2169,13 +2255,22 @@ dependencies = [
|
||||
"getrandom 0.2.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
|
||||
dependencies = [
|
||||
"rand_core 0.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
"rand_core 0.6.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2184,7 +2279,7 @@ version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
"rand_core 0.6.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2615,8 +2710,8 @@ dependencies = [
|
||||
"derivative",
|
||||
"digest 0.9.0",
|
||||
"itertools 0.10.0",
|
||||
"rand",
|
||||
"rand_chacha",
|
||||
"rand 0.8.3",
|
||||
"rand_chacha 0.3.0",
|
||||
"rayon",
|
||||
"sha2",
|
||||
"smallvec",
|
||||
@ -2635,7 +2730,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64610b135b8b1152439d5dfa4f745515933366082f08651961344aa0bb5abfca"
|
||||
dependencies = [
|
||||
"derivative",
|
||||
"rand",
|
||||
"rand 0.8.3",
|
||||
"rand_xorshift",
|
||||
"rustc_version 0.3.3",
|
||||
"serde",
|
||||
@ -2670,7 +2765,7 @@ dependencies = [
|
||||
"derivative",
|
||||
"hex",
|
||||
"itertools 0.10.0",
|
||||
"rand",
|
||||
"rand 0.8.3",
|
||||
"snarkvm-algorithms",
|
||||
"snarkvm-curves",
|
||||
"snarkvm-fields",
|
||||
@ -2691,7 +2786,7 @@ checksum = "8c49c69d02df11be58e07f626c9d6f5804c6dd4ccf42e425f2be8d79fe6e5bb7"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"derivative",
|
||||
"rand",
|
||||
"rand 0.8.3",
|
||||
"rand_xorshift",
|
||||
"serde",
|
||||
"snarkvm-utilities",
|
||||
@ -2726,7 +2821,7 @@ dependencies = [
|
||||
"chrono",
|
||||
"hex",
|
||||
"once_cell",
|
||||
"rand",
|
||||
"rand 0.8.3",
|
||||
"serde",
|
||||
"sha2",
|
||||
"snarkvm-algorithms",
|
||||
@ -2780,7 +2875,7 @@ dependencies = [
|
||||
"bincode",
|
||||
"hex",
|
||||
"parking_lot",
|
||||
"rand",
|
||||
"rand 0.8.3",
|
||||
"rocksdb",
|
||||
"serde",
|
||||
"snarkvm-algorithms",
|
||||
@ -2798,7 +2893,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c763843fa67a3aa4ce68173c8cd96b4f04aaa135a5792bc051c36eec0fe1cd73"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"rand",
|
||||
"rand 0.8.3",
|
||||
"snarkvm-derives",
|
||||
"thiserror",
|
||||
]
|
||||
@ -2904,7 +2999,7 @@ checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"rand",
|
||||
"rand 0.8.3",
|
||||
"redox_syscall 0.2.5",
|
||||
"remove_dir_all",
|
||||
"winapi 0.3.9",
|
||||
@ -2940,6 +3035,15 @@ dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "test_dir"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e571ebf9127a9da821890a9fa8a8ef777fce3e0f959ff6949cf06ca8b736381d"
|
||||
dependencies = [
|
||||
"rand 0.7.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.11.0"
|
||||
@ -3152,6 +3256,12 @@ dependencies = [
|
||||
"tracing-serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "treeline"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41"
|
||||
|
||||
[[package]]
|
||||
name = "try-lock"
|
||||
version = "0.2.3"
|
||||
@ -3269,6 +3379,15 @@ version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||
|
||||
[[package]]
|
||||
name = "wait-timeout"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.3.2"
|
||||
|
@ -157,6 +157,12 @@ version = "0.12.1"
|
||||
[dev-dependencies.rusty-hook]
|
||||
version = "0.11.2"
|
||||
|
||||
[dev-dependencies.assert_cmd]
|
||||
version = "1.0.3"
|
||||
|
||||
[dev-dependencies.test_dir]
|
||||
version = "0.1.0"
|
||||
|
||||
[features]
|
||||
default = [ ]
|
||||
ci_skip = [ "leo-compiler/ci_skip" ]
|
||||
|
14
examples/silly-sudoku/inputs/test_input.in
Normal file
14
examples/silly-sudoku/inputs/test_input.in
Normal file
@ -0,0 +1,14 @@
|
||||
// The program input for tmp-test/src/main.leo
|
||||
[main]
|
||||
puzzle: [u8; (3, 3)] = [[1, 0, 5],
|
||||
[0, 2, 0],
|
||||
[7, 0, 0]];
|
||||
|
||||
answer: [u8; (3, 3)] = [[1, 4, 5],
|
||||
[3, 2, 6],
|
||||
[7, 8, 9]];
|
||||
|
||||
expected: bool = true;
|
||||
|
||||
[registers]
|
||||
r: bool = false;
|
@ -22,11 +22,11 @@ use leo_compiler::{
|
||||
use leo_package::{
|
||||
inputs::*,
|
||||
outputs::{ChecksumFile, CircuitFile, OutputsDirectory, OUTPUTS_DIRECTORY_NAME},
|
||||
source::{LibraryFile, MainFile, LIBRARY_FILENAME, MAIN_FILENAME, SOURCE_DIRECTORY_NAME},
|
||||
source::{MainFile, MAIN_FILENAME, SOURCE_DIRECTORY_NAME},
|
||||
};
|
||||
use leo_synthesizer::{CircuitSynthesizer, SerializedCircuit};
|
||||
|
||||
use anyhow::Result;
|
||||
use anyhow::{anyhow, Result};
|
||||
use snarkvm_curves::{bls12_377::Bls12_377, edwards_bls12::Fq};
|
||||
use snarkvm_r1cs::ConstraintSystem;
|
||||
use structopt::StructOpt;
|
||||
@ -39,7 +39,7 @@ pub struct Build {}
|
||||
|
||||
impl Command for Build {
|
||||
type Input = ();
|
||||
type Output = Option<(Compiler<'static, Fq, EdwardsGroupType>, bool)>;
|
||||
type Output = (Compiler<'static, Fq, EdwardsGroupType>, bool);
|
||||
|
||||
fn log_span(&self) -> Span {
|
||||
tracing::span!(tracing::Level::INFO, "Build")
|
||||
@ -65,115 +65,95 @@ impl Command for Build {
|
||||
|
||||
tracing::info!("Starting...");
|
||||
|
||||
// Compile the package starting with the lib.leo file
|
||||
if LibraryFile::exists_at(&package_path) {
|
||||
// Construct the path to the library file in the source directory
|
||||
let mut lib_file_path = package_path.clone();
|
||||
lib_file_path.push(SOURCE_DIRECTORY_NAME);
|
||||
lib_file_path.push(LIBRARY_FILENAME);
|
||||
|
||||
// Log compilation of library file to console
|
||||
tracing::info!("Compiling library... ({:?})", lib_file_path);
|
||||
|
||||
// Compile the library file but do not output
|
||||
let _program = Compiler::<Fq, EdwardsGroupType>::parse_program_without_input(
|
||||
package_name.clone(),
|
||||
lib_file_path,
|
||||
output_directory.clone(),
|
||||
thread_leaked_context(),
|
||||
)?;
|
||||
tracing::info!("Complete");
|
||||
};
|
||||
|
||||
// Compile the main.leo file along with constraints
|
||||
if MainFile::exists_at(&package_path) {
|
||||
// Create the output directory
|
||||
OutputsDirectory::create(&package_path)?;
|
||||
|
||||
// Construct the path to the main file in the source directory
|
||||
let mut main_file_path = package_path.clone();
|
||||
main_file_path.push(SOURCE_DIRECTORY_NAME);
|
||||
main_file_path.push(MAIN_FILENAME);
|
||||
|
||||
// Load the input file at `package_name.in`
|
||||
let (input_string, input_path) = InputFile::new(&package_name).read_from(&path)?;
|
||||
|
||||
// Load the state file at `package_name.in`
|
||||
let (state_string, state_path) = StateFile::new(&package_name).read_from(&path)?;
|
||||
|
||||
// Log compilation of files to console
|
||||
tracing::info!("Compiling main program... ({:?})", main_file_path);
|
||||
|
||||
// Load the program at `main_file_path`
|
||||
let program = Compiler::<Fq, EdwardsGroupType>::parse_program_with_input(
|
||||
package_name.clone(),
|
||||
main_file_path,
|
||||
output_directory,
|
||||
&input_string,
|
||||
&input_path,
|
||||
&state_string,
|
||||
&state_path,
|
||||
thread_leaked_context(),
|
||||
)?;
|
||||
|
||||
// Compute the current program checksum
|
||||
let program_checksum = program.checksum()?;
|
||||
|
||||
// Generate the program on the constraint system and verify correctness
|
||||
{
|
||||
let mut cs = CircuitSynthesizer::<Bls12_377> {
|
||||
constraints: Default::default(),
|
||||
public_variables: Default::default(),
|
||||
private_variables: Default::default(),
|
||||
namespaces: Default::default(),
|
||||
};
|
||||
let temporary_program = program.clone();
|
||||
let output = temporary_program.compile_constraints(&mut cs)?;
|
||||
|
||||
tracing::debug!("Compiled output - {:#?}", output);
|
||||
tracing::info!("Number of constraints - {:#?}", cs.num_constraints());
|
||||
|
||||
// Serialize the circuit
|
||||
let circuit_object = SerializedCircuit::from(cs);
|
||||
let json = circuit_object.to_json_string().unwrap();
|
||||
// println!("json: {}", json);
|
||||
|
||||
// Write serialized circuit to circuit `.json` file.
|
||||
let circuit_file = CircuitFile::new(&package_name);
|
||||
circuit_file.write_to(&path, json)?;
|
||||
|
||||
// Check that we can read the serialized circuit file
|
||||
// let serialized = circuit_file.read_from(&package_path)?;
|
||||
|
||||
// Deserialize the circuit
|
||||
// let deserialized = SerializedCircuit::from_json_string(&serialized).unwrap();
|
||||
// let _circuit_synthesizer = CircuitSynthesizer::<Bls12_377>::try_from(deserialized).unwrap();
|
||||
// println!("deserialized {:?}", circuit_synthesizer.num_constraints());
|
||||
}
|
||||
|
||||
// If a checksum file exists, check if it differs from the new checksum
|
||||
let checksum_file = ChecksumFile::new(&package_name);
|
||||
let checksum_differs = if checksum_file.exists_at(&package_path) {
|
||||
let previous_checksum = checksum_file.read_from(&package_path)?;
|
||||
program_checksum != previous_checksum
|
||||
} else {
|
||||
// By default, the checksum differs if there is no checksum to compare against
|
||||
true
|
||||
};
|
||||
|
||||
// If checksum differs, compile the program
|
||||
if checksum_differs {
|
||||
// Write the new checksum to the output directory
|
||||
checksum_file.write_to(&path, program_checksum)?;
|
||||
|
||||
tracing::debug!("Checksum saved ({:?})", path);
|
||||
}
|
||||
|
||||
tracing::info!("Complete");
|
||||
|
||||
return Ok(Some((program, checksum_differs)));
|
||||
if !MainFile::exists_at(&package_path) {
|
||||
return Err(anyhow!("File main.leo not found in src/ directory"));
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
// Create the output directory
|
||||
OutputsDirectory::create(&package_path)?;
|
||||
|
||||
// Construct the path to the main file in the source directory
|
||||
let mut main_file_path = package_path.clone();
|
||||
main_file_path.push(SOURCE_DIRECTORY_NAME);
|
||||
main_file_path.push(MAIN_FILENAME);
|
||||
|
||||
// Load the input file at `package_name.in`
|
||||
let (input_string, input_path) = InputFile::new(&package_name).read_from(&path)?;
|
||||
|
||||
// Load the state file at `package_name.in`
|
||||
let (state_string, state_path) = StateFile::new(&package_name).read_from(&path)?;
|
||||
|
||||
// Log compilation of files to console
|
||||
tracing::info!("Compiling main program... ({:?})", main_file_path);
|
||||
|
||||
// Load the program at `main_file_path`
|
||||
let program = Compiler::<Fq, EdwardsGroupType>::parse_program_with_input(
|
||||
package_name.clone(),
|
||||
main_file_path,
|
||||
output_directory,
|
||||
&input_string,
|
||||
&input_path,
|
||||
&state_string,
|
||||
&state_path,
|
||||
thread_leaked_context(),
|
||||
)?;
|
||||
|
||||
// Compute the current program checksum
|
||||
let program_checksum = program.checksum()?;
|
||||
|
||||
// Generate the program on the constraint system and verify correctness
|
||||
{
|
||||
let mut cs = CircuitSynthesizer::<Bls12_377> {
|
||||
constraints: Default::default(),
|
||||
public_variables: Default::default(),
|
||||
private_variables: Default::default(),
|
||||
namespaces: Default::default(),
|
||||
};
|
||||
let temporary_program = program.clone();
|
||||
let output = temporary_program.compile_constraints(&mut cs)?;
|
||||
|
||||
tracing::debug!("Compiled output - {:#?}", output);
|
||||
tracing::info!("Number of constraints - {:#?}", cs.num_constraints());
|
||||
|
||||
// Serialize the circuit
|
||||
let circuit_object = SerializedCircuit::from(cs);
|
||||
let json = circuit_object.to_json_string().unwrap();
|
||||
// println!("json: {}", json);
|
||||
|
||||
// Write serialized circuit to circuit `.json` file.
|
||||
let circuit_file = CircuitFile::new(&package_name);
|
||||
circuit_file.write_to(&path, json)?;
|
||||
|
||||
// Check that we can read the serialized circuit file
|
||||
// let serialized = circuit_file.read_from(&package_path)?;
|
||||
|
||||
// Deserialize the circuit
|
||||
// let deserialized = SerializedCircuit::from_json_string(&serialized).unwrap();
|
||||
// let _circuit_synthesizer = CircuitSynthesizer::<Bls12_377>::try_from(deserialized).unwrap();
|
||||
// println!("deserialized {:?}", circuit_synthesizer.num_constraints());
|
||||
}
|
||||
|
||||
// If a checksum file exists, check if it differs from the new checksum
|
||||
let checksum_file = ChecksumFile::new(&package_name);
|
||||
let checksum_differs = if checksum_file.exists_at(&package_path) {
|
||||
let previous_checksum = checksum_file.read_from(&package_path)?;
|
||||
program_checksum != previous_checksum
|
||||
} else {
|
||||
// By default, the checksum differs if there is no checksum to compare against
|
||||
true
|
||||
};
|
||||
|
||||
// If checksum differs, compile the program
|
||||
if checksum_differs {
|
||||
// Write the new checksum to the output directory
|
||||
checksum_file.write_to(&path, program_checksum)?;
|
||||
|
||||
tracing::debug!("Checksum saved ({:?})", path);
|
||||
}
|
||||
|
||||
tracing::info!("Complete");
|
||||
|
||||
Ok((program, checksum_differs))
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ use crate::{commands::Command, config::*, context::Context};
|
||||
use leo_package::LeoPackage;
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use std::env::current_dir;
|
||||
use structopt::StructOpt;
|
||||
use tracing::span::Span;
|
||||
|
||||
@ -39,9 +38,9 @@ impl Command for Init {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn apply(self, _: Context, _: Self::Input) -> Result<Self::Output> {
|
||||
fn apply(self, context: Context, _: Self::Input) -> Result<Self::Output> {
|
||||
// Derive the package directory path.
|
||||
let path = current_dir()?;
|
||||
let path = context.dir()?;
|
||||
|
||||
// Check that the current package directory path exists.
|
||||
if !path.exists() {
|
||||
@ -55,12 +54,12 @@ impl Command for Init {
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
if !LeoPackage::is_package_name_valid(&package_name) {
|
||||
return Err(anyhow!("Invalid Leo project name"));
|
||||
return Err(anyhow!("Invalid Leo project name: {}", package_name));
|
||||
}
|
||||
|
||||
let username = read_username().ok();
|
||||
|
||||
LeoPackage::initialize(&package_name, false, &path, username)?;
|
||||
LeoPackage::initialize(&package_name, &path, username)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ use crate::{commands::Command, config::*, context::Context};
|
||||
use leo_package::LeoPackage;
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use std::{env::current_dir, fs};
|
||||
use std::fs;
|
||||
use structopt::StructOpt;
|
||||
use tracing::span::Span;
|
||||
|
||||
@ -42,7 +42,7 @@ impl Command for New {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn apply(self, _: Context, _: Self::Input) -> Result<Self::Output> {
|
||||
fn apply(self, context: Context, _: Self::Input) -> Result<Self::Output> {
|
||||
// Check that the given package name is valid.
|
||||
let package_name = self.name;
|
||||
if !LeoPackage::is_package_name_valid(&package_name) {
|
||||
@ -52,7 +52,7 @@ impl Command for New {
|
||||
let username = read_username().ok();
|
||||
|
||||
// Derive the package directory path.
|
||||
let mut path = current_dir()?;
|
||||
let mut path = context.dir()?;
|
||||
path.push(&package_name);
|
||||
|
||||
// Verify the package directory path does not exist yet.
|
||||
@ -63,7 +63,7 @@ impl Command for New {
|
||||
// Create the package directory
|
||||
fs::create_dir_all(&path).map_err(|err| anyhow!("Could not create directory {}", err))?;
|
||||
|
||||
LeoPackage::initialize(&package_name, false, &path, username)?;
|
||||
LeoPackage::initialize(&package_name, &path, username)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -58,8 +58,7 @@ impl Command for Setup {
|
||||
let package_name = context.manifest()?.get_package_name();
|
||||
|
||||
// Check if leo build failed
|
||||
let (program, checksum_differs) =
|
||||
input.ok_or_else(|| anyhow!("Unable to build, check that main file exists"))?;
|
||||
let (program, checksum_differs) = input;
|
||||
|
||||
// Check if a proving key and verification key already exists
|
||||
let keys_exist = ProvingKeyFile::new(&package_name).exists_at(&path)
|
||||
|
@ -21,7 +21,7 @@ use structopt::StructOpt;
|
||||
use tracing::span::Span;
|
||||
|
||||
/// Setting for automatic updates of Leo
|
||||
#[derive(Debug, StructOpt, PartialEq)]
|
||||
#[derive(Debug, StructOpt)]
|
||||
pub enum Automatic {
|
||||
Automatic {
|
||||
#[structopt(name = "bool", help = "Boolean value: true or false", parse(try_from_str))]
|
||||
|
@ -65,13 +65,8 @@ impl Command for Watch {
|
||||
// See changes on the write event
|
||||
Ok(DebouncedEvent::Write(_write)) => {
|
||||
match (Build {}).execute(context.clone()) {
|
||||
Ok(_output) => {
|
||||
tracing::info!("Built successfully");
|
||||
}
|
||||
Err(e) => {
|
||||
// Syntax error
|
||||
tracing::error!("Error {:?}", e);
|
||||
}
|
||||
Ok(_output) => tracing::info!("Built successfully"),
|
||||
Err(e) => tracing::error!("Error {:?}", e),
|
||||
};
|
||||
}
|
||||
// Other events
|
||||
|
@ -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 std::fmt;
|
||||
use std::{fmt, sync::Once};
|
||||
|
||||
use colored::Colorize;
|
||||
use tracing::{event::Event, subscriber::Subscriber};
|
||||
@ -24,6 +24,8 @@ use tracing_subscriber::{
|
||||
FmtSubscriber,
|
||||
};
|
||||
|
||||
static START: Once = Once::new();
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Format<F = Full, T = SystemTime> {
|
||||
format: F,
|
||||
@ -220,5 +222,8 @@ pub fn init_logger(_app_name: &'static str, verbosity: usize) {
|
||||
.event_format(Format::default())
|
||||
.finish();
|
||||
|
||||
tracing::subscriber::set_global_default(subscriber).expect("setting default subscriber failed");
|
||||
// call this line only once per process. needed for tests using same thread
|
||||
START.call_once(|| {
|
||||
tracing::subscriber::set_global_default(subscriber).expect("setting default subscriber failed");
|
||||
});
|
||||
}
|
||||
|
147
leo/main.rs
147
leo/main.rs
@ -181,9 +181,11 @@ enum CommandOpts {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Read command line arguments.
|
||||
let opt = Opt::from_args();
|
||||
handle_error(run_with_args(Opt::from_args()))
|
||||
}
|
||||
|
||||
/// Run command with custom build arguments.
|
||||
fn run_with_args(opt: Opt) -> Result<(), Error> {
|
||||
if !opt.quiet {
|
||||
// Init logger with optional debug flag.
|
||||
logger::init_logger("leo", match opt.debug {
|
||||
@ -199,7 +201,7 @@ fn main() {
|
||||
None => context::get_context(opt.api),
|
||||
});
|
||||
|
||||
handle_error(match opt.command {
|
||||
match opt.command {
|
||||
CommandOpts::Init { command } => command.try_execute(context),
|
||||
CommandOpts::New { command } => command.try_execute(context),
|
||||
CommandOpts::Build { command } => command.try_execute(context),
|
||||
@ -220,7 +222,7 @@ fn main() {
|
||||
|
||||
CommandOpts::Lint { command } => command.try_execute(context),
|
||||
CommandOpts::Deploy { command } => command.try_execute(context),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_error<T>(res: Result<T, Error>) -> T {
|
||||
@ -232,3 +234,140 @@ fn handle_error<T>(res: Result<T, Error>) -> T {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod cli_tests {
|
||||
use crate::{run_with_args, Opt};
|
||||
|
||||
use anyhow::Error;
|
||||
use std::path::PathBuf;
|
||||
use structopt::StructOpt;
|
||||
use test_dir::{DirBuilder, FileType, TestDir};
|
||||
|
||||
// Runs Command from cmd-like argument "leo run --arg1 --arg2".
|
||||
fn run_cmd(args: &str, path: &Option<PathBuf>) -> Result<(), Error> {
|
||||
let args = args.split(' ').collect::<Vec<&str>>();
|
||||
let mut opts = Opt::from_iter_safe(args)?;
|
||||
|
||||
if path.is_some() {
|
||||
opts.path = path.clone();
|
||||
}
|
||||
|
||||
if !opts.debug {
|
||||
// turn off tracing for all tests
|
||||
opts.quiet = true;
|
||||
}
|
||||
|
||||
run_with_args(opts)
|
||||
}
|
||||
|
||||
// Create a test directory with name.
|
||||
fn testdir(name: &str) -> TestDir {
|
||||
TestDir::temp().create(name, FileType::Dir)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn global_options() {
|
||||
let path = Some(PathBuf::from("examples/pedersen-hash"));
|
||||
|
||||
assert!(run_cmd("leo build", &path).is_ok());
|
||||
assert!(run_cmd("leo -q build", &path).is_ok());
|
||||
|
||||
assert!(run_cmd("leo --path ../../examples/no-directory-there build", &None).is_err());
|
||||
assert!(run_cmd("leo -v build", &None).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn global_options_fail() {
|
||||
assert!(run_cmd("leo --path ../../examples/no-directory-there build", &None).is_err());
|
||||
assert!(run_cmd("leo -v build", &None).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn init() {
|
||||
let dir = testdir("test");
|
||||
let path = Some(dir.path("test"));
|
||||
|
||||
assert!(run_cmd("leo init", &path).is_ok());
|
||||
assert!(run_cmd("leo init", &path).is_err()); // 2nd time
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn init_fail() {
|
||||
let dir = testdir("incorrect_name");
|
||||
let path = Some(dir.path("incorrect_name"));
|
||||
let fake = Some(PathBuf::from("no_such_directory"));
|
||||
|
||||
assert!(run_cmd("leo init", &fake).is_err());
|
||||
assert!(run_cmd("leo init", &path).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn new() {
|
||||
let dir = testdir("new");
|
||||
let path = Some(dir.path("new"));
|
||||
|
||||
assert!(run_cmd("leo new test", &path).is_ok());
|
||||
assert!(run_cmd("leo new test", &path).is_err()); // 2nd time
|
||||
assert!(run_cmd("leo new wrong_name", &path).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn unimplemented() {
|
||||
assert!(run_cmd("leo lint", &None).is_err());
|
||||
assert!(run_cmd("leo deploy", &None).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn clean() {
|
||||
let path = &Some(PathBuf::from("examples/pedersen-hash"));
|
||||
|
||||
assert!(run_cmd("leo build", path).is_ok());
|
||||
assert!(run_cmd("leo clean", path).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn setup_prove_run_clean() {
|
||||
let dir = testdir("test");
|
||||
let path = dir.path("test");
|
||||
|
||||
assert!(run_cmd("leo new setup-test", &Some(path.clone())).is_ok());
|
||||
|
||||
let setup_path = &Some(path.join("setup-test"));
|
||||
|
||||
assert!(run_cmd("leo setup", setup_path).is_ok());
|
||||
assert!(run_cmd("leo setup", setup_path).is_ok());
|
||||
assert!(run_cmd("leo setup --skip-key-check", setup_path).is_ok());
|
||||
assert!(run_cmd("leo prove --skip-key-check", setup_path).is_ok());
|
||||
assert!(run_cmd("leo run --skip-key-check", setup_path).is_ok());
|
||||
assert!(run_cmd("leo clean", setup_path).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_missing_file() {
|
||||
let dir = testdir("test");
|
||||
let path = dir.path("test");
|
||||
|
||||
assert!(run_cmd("leo new test-file-missing", &Some(path.clone())).is_ok());
|
||||
|
||||
let path = path.join("test-file-missing");
|
||||
let file = path.join("src/main.leo");
|
||||
let path = Some(path);
|
||||
|
||||
assert!(run_cmd("leo test", &path).is_ok());
|
||||
std::fs::remove_file(&file).unwrap();
|
||||
assert!(run_cmd("leo test", &path).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore] // ignore until imports path is fixed #875
|
||||
fn test_sudoku() {
|
||||
let path = &Some(PathBuf::from("examples/silly-sudoku"));
|
||||
|
||||
assert!(run_cmd("leo build", path).is_ok());
|
||||
assert!(run_cmd("leo test", path).is_ok());
|
||||
assert!(run_cmd("leo test -f src/lib.leo", path).is_ok());
|
||||
assert!(run_cmd("leo test -f src/main.leo", path).is_ok());
|
||||
}
|
||||
}
|
||||
|
@ -14,9 +14,8 @@
|
||||
// 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 std::path::PathBuf;
|
||||
|
||||
use anyhow::Result;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::{
|
||||
commands::{
|
||||
|
@ -33,13 +33,8 @@ pub struct LeoPackage;
|
||||
|
||||
impl LeoPackage {
|
||||
/// Initializes a Leo package at the given path.
|
||||
pub fn initialize(
|
||||
package_name: &str,
|
||||
is_lib: bool,
|
||||
path: &Path,
|
||||
author: Option<String>,
|
||||
) -> Result<(), PackageError> {
|
||||
package::Package::initialize(package_name, is_lib, path, author)
|
||||
pub fn initialize(package_name: &str, path: &Path, author: Option<String>) -> Result<(), PackageError> {
|
||||
package::Package::initialize(package_name, path, author)
|
||||
}
|
||||
|
||||
/// Returns `true` if the given Leo package name is valid.
|
||||
|
@ -19,7 +19,7 @@ use crate::{
|
||||
imports::ImportsDirectory,
|
||||
inputs::{InputFile, InputsDirectory, StateFile},
|
||||
root::{Gitignore, Manifest, README},
|
||||
source::{LibraryFile, MainFile, SourceDirectory},
|
||||
source::{MainFile, SourceDirectory},
|
||||
};
|
||||
|
||||
use serde::Deserialize;
|
||||
@ -107,7 +107,7 @@ impl Package {
|
||||
}
|
||||
|
||||
/// Returns `true` if a package is can be initialized at a given path.
|
||||
pub fn can_initialize(package_name: &str, is_lib: bool, path: &Path) -> bool {
|
||||
pub fn can_initialize(package_name: &str, path: &Path) -> bool {
|
||||
// Check that the package name is valid.
|
||||
if !Self::is_package_name_valid(package_name) {
|
||||
return false;
|
||||
@ -122,32 +122,24 @@ impl Package {
|
||||
result = false;
|
||||
}
|
||||
|
||||
if is_lib {
|
||||
// Check if the library file already exists.
|
||||
if LibraryFile::exists_at(path) {
|
||||
existing_files.push(LibraryFile::filename());
|
||||
result = false;
|
||||
}
|
||||
} else {
|
||||
// Check if the input file already exists.
|
||||
let input_file = InputFile::new(&package_name);
|
||||
if input_file.exists_at(path) {
|
||||
existing_files.push(input_file.filename());
|
||||
result = false;
|
||||
}
|
||||
// Check if the input file already exists.
|
||||
let input_file = InputFile::new(&package_name);
|
||||
if input_file.exists_at(path) {
|
||||
existing_files.push(input_file.filename());
|
||||
result = false;
|
||||
}
|
||||
|
||||
// Check if the state file already exists.
|
||||
let state_file = StateFile::new(&package_name);
|
||||
if state_file.exists_at(path) {
|
||||
existing_files.push(state_file.filename());
|
||||
result = false;
|
||||
}
|
||||
// Check if the state file already exists.
|
||||
let state_file = StateFile::new(&package_name);
|
||||
if state_file.exists_at(path) {
|
||||
existing_files.push(state_file.filename());
|
||||
result = false;
|
||||
}
|
||||
|
||||
// Check if the main file already exists.
|
||||
if MainFile::exists_at(path) {
|
||||
existing_files.push(MainFile::filename());
|
||||
result = false;
|
||||
}
|
||||
// Check if the main file already exists.
|
||||
if MainFile::exists_at(path) {
|
||||
existing_files.push(MainFile::filename());
|
||||
result = false;
|
||||
}
|
||||
|
||||
if !existing_files.is_empty() {
|
||||
@ -158,7 +150,7 @@ impl Package {
|
||||
}
|
||||
|
||||
/// Returns `true` if a package is initialized at the given path
|
||||
pub fn is_initialized(package_name: &str, is_lib: bool, path: &Path) -> bool {
|
||||
pub fn is_initialized(package_name: &str, path: &Path) -> bool {
|
||||
// Check that the package name is valid.
|
||||
if !Self::is_package_name_valid(package_name) {
|
||||
return false;
|
||||
@ -169,43 +161,31 @@ impl Package {
|
||||
return false;
|
||||
}
|
||||
|
||||
if is_lib {
|
||||
// Check if the library file exists.
|
||||
if !LibraryFile::exists_at(&path) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Check if the input file exists.
|
||||
let input_file = InputFile::new(&package_name);
|
||||
if !input_file.exists_at(&path) {
|
||||
return false;
|
||||
}
|
||||
// Check if the input file exists.
|
||||
let input_file = InputFile::new(&package_name);
|
||||
if !input_file.exists_at(&path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the state file exists.
|
||||
let state_file = StateFile::new(&package_name);
|
||||
if !state_file.exists_at(&path) {
|
||||
return false;
|
||||
}
|
||||
// Check if the state file exists.
|
||||
let state_file = StateFile::new(&package_name);
|
||||
if !state_file.exists_at(&path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the main file exists.
|
||||
if !MainFile::exists_at(&path) {
|
||||
return false;
|
||||
}
|
||||
// Check if the main file exists.
|
||||
if !MainFile::exists_at(&path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
/// Creates a package at the given path
|
||||
pub fn initialize(
|
||||
package_name: &str,
|
||||
is_lib: bool,
|
||||
path: &Path,
|
||||
author: Option<String>,
|
||||
) -> Result<(), PackageError> {
|
||||
pub fn initialize(package_name: &str, path: &Path, author: Option<String>) -> Result<(), PackageError> {
|
||||
// First, verify that this directory is not already initialized as a Leo package.
|
||||
{
|
||||
if !Self::can_initialize(package_name, is_lib, path) {
|
||||
if !Self::can_initialize(package_name, path) {
|
||||
return Err(PackageError::FailedToInitialize(
|
||||
package_name.to_owned(),
|
||||
path.as_os_str().to_owned(),
|
||||
@ -232,27 +212,21 @@ impl Package {
|
||||
// Create the source directory.
|
||||
SourceDirectory::create(&path)?;
|
||||
|
||||
// Create a new library or binary file.
|
||||
if is_lib {
|
||||
// Create the library file in the source directory.
|
||||
LibraryFile::new(&package_name).write_to(&path)?;
|
||||
} else {
|
||||
// Create the input directory.
|
||||
InputsDirectory::create(&path)?;
|
||||
// Create the input directory.
|
||||
InputsDirectory::create(&path)?;
|
||||
|
||||
// Create the input file in the inputs directory.
|
||||
InputFile::new(&package_name).write_to(&path)?;
|
||||
// Create the input file in the inputs directory.
|
||||
InputFile::new(&package_name).write_to(&path)?;
|
||||
|
||||
// Create the state file in the inputs directory.
|
||||
StateFile::new(&package_name).write_to(&path)?;
|
||||
// Create the state file in the inputs directory.
|
||||
StateFile::new(&package_name).write_to(&path)?;
|
||||
|
||||
// Create the main file in the source directory.
|
||||
MainFile::new(&package_name).write_to(&path)?;
|
||||
}
|
||||
// Create the main file in the source directory.
|
||||
MainFile::new(&package_name).write_to(&path)?;
|
||||
}
|
||||
// Next, verify that a valid Leo package has been initialized in this directory
|
||||
{
|
||||
if !Self::is_initialized(package_name, is_lib, path) {
|
||||
if !Self::is_initialized(package_name, path) {
|
||||
return Err(PackageError::FailedToInitialize(
|
||||
package_name.to_owned(),
|
||||
path.as_os_str().to_owned(),
|
||||
|
@ -1,76 +0,0 @@
|
||||
// Copyright (C) 2019-2021 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/>.
|
||||
|
||||
//! The `lib.leo` file.
|
||||
|
||||
use crate::{errors::LibraryFileError, source::directory::SOURCE_DIRECTORY_NAME};
|
||||
|
||||
use serde::Deserialize;
|
||||
use std::{borrow::Cow, fs::File, io::Write, path::Path};
|
||||
|
||||
pub static LIBRARY_FILENAME: &str = "lib.leo";
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct LibraryFile {
|
||||
pub package_name: String,
|
||||
}
|
||||
|
||||
impl LibraryFile {
|
||||
pub fn new(package_name: &str) -> Self {
|
||||
Self {
|
||||
package_name: package_name.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn filename() -> String {
|
||||
format!("{}{}", SOURCE_DIRECTORY_NAME, LIBRARY_FILENAME)
|
||||
}
|
||||
|
||||
pub fn exists_at(path: &Path) -> bool {
|
||||
let mut path = Cow::from(path);
|
||||
if path.is_dir() {
|
||||
if !path.ends_with(SOURCE_DIRECTORY_NAME) {
|
||||
path.to_mut().push(SOURCE_DIRECTORY_NAME);
|
||||
}
|
||||
path.to_mut().push(LIBRARY_FILENAME);
|
||||
}
|
||||
path.exists()
|
||||
}
|
||||
|
||||
pub fn write_to(self, path: &Path) -> Result<(), LibraryFileError> {
|
||||
let mut path = Cow::from(path);
|
||||
if path.is_dir() {
|
||||
if !path.ends_with(SOURCE_DIRECTORY_NAME) {
|
||||
path.to_mut().push(SOURCE_DIRECTORY_NAME);
|
||||
}
|
||||
path.to_mut().push(LIBRARY_FILENAME);
|
||||
}
|
||||
|
||||
let mut file = File::create(&path)?;
|
||||
Ok(file.write_all(self.template().as_bytes())?)
|
||||
}
|
||||
|
||||
fn template(&self) -> String {
|
||||
format!(
|
||||
r#"// The '{}' library circuit.
|
||||
circuit Foo {{
|
||||
a: field
|
||||
}}
|
||||
"#,
|
||||
self.package_name
|
||||
)
|
||||
}
|
||||
}
|
@ -17,8 +17,5 @@
|
||||
pub mod directory;
|
||||
pub use directory::*;
|
||||
|
||||
pub mod library;
|
||||
pub use library::*;
|
||||
|
||||
pub mod main;
|
||||
pub use main::*;
|
||||
|
@ -19,7 +19,7 @@ use leo_package::{
|
||||
inputs::{InputFile, InputsDirectory, StateFile},
|
||||
package::Package,
|
||||
root::Manifest,
|
||||
source::{LibraryFile, MainFile, SourceDirectory},
|
||||
source::{MainFile, SourceDirectory},
|
||||
};
|
||||
|
||||
const TEST_PACKAGE_NAME: &str = "test-package";
|
||||
@ -29,13 +29,13 @@ fn initialize_valid_package() {
|
||||
let test_directory = test_dir();
|
||||
|
||||
// Ensure a package can be initialized at the `test_directory`
|
||||
assert!(Package::can_initialize(TEST_PACKAGE_NAME, false, &test_directory));
|
||||
assert!(Package::can_initialize(TEST_PACKAGE_NAME, &test_directory));
|
||||
|
||||
// Initialize a package at the `test_directory`
|
||||
assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory, None).is_ok());
|
||||
assert!(Package::initialize(TEST_PACKAGE_NAME, &test_directory, None).is_ok());
|
||||
|
||||
// Ensure a package is initialized at the `test_directory`
|
||||
assert!(Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory));
|
||||
assert!(Package::is_initialized(TEST_PACKAGE_NAME, &test_directory));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -43,21 +43,13 @@ fn initialize_valid_package_with_author() {
|
||||
let test_directory = test_dir();
|
||||
|
||||
// Ensure a package can be initialized at the `test_directory`
|
||||
assert!(Package::can_initialize(TEST_PACKAGE_NAME, false, &test_directory));
|
||||
assert!(Package::can_initialize(TEST_PACKAGE_NAME, &test_directory));
|
||||
|
||||
// Initialize a package at the `test_directory`
|
||||
assert!(
|
||||
Package::initialize(
|
||||
TEST_PACKAGE_NAME,
|
||||
false,
|
||||
&test_directory,
|
||||
Some(String::from("test_user"))
|
||||
)
|
||||
.is_ok()
|
||||
);
|
||||
assert!(Package::initialize(TEST_PACKAGE_NAME, &test_directory, Some(String::from("test_user"))).is_ok());
|
||||
|
||||
// Ensure a package is initialized at the `test_directory`
|
||||
assert!(Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory));
|
||||
assert!(Package::is_initialized(TEST_PACKAGE_NAME, &test_directory));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -71,7 +63,7 @@ fn initialize_fails_with_existing_manifest() {
|
||||
let test_directory = test_dir();
|
||||
|
||||
// Ensure a package can be initialized at the `test_directory`
|
||||
assert!(Package::can_initialize(TEST_PACKAGE_NAME, false, &test_directory));
|
||||
assert!(Package::can_initialize(TEST_PACKAGE_NAME, &test_directory));
|
||||
|
||||
// Manually add a manifest file to the `test_directory`
|
||||
Manifest::new(TEST_PACKAGE_NAME, None)
|
||||
@ -80,28 +72,10 @@ fn initialize_fails_with_existing_manifest() {
|
||||
.unwrap();
|
||||
|
||||
// Attempt to initialize a package at the `test_directory`
|
||||
assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory, None).is_err());
|
||||
assert!(Package::initialize(TEST_PACKAGE_NAME, &test_directory, None).is_err());
|
||||
|
||||
// Ensure package is not initialized at the `test_directory`
|
||||
assert!(!Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn initialize_fails_with_existing_library_file() {
|
||||
let test_directory = test_dir();
|
||||
|
||||
// Ensure a package can be initialized at the `test_directory`
|
||||
assert!(Package::can_initialize(TEST_PACKAGE_NAME, true, &test_directory));
|
||||
|
||||
// Manually add a source directory and a library file to the `test_directory`
|
||||
SourceDirectory::create(&test_directory).unwrap();
|
||||
LibraryFile::new(TEST_PACKAGE_NAME).write_to(&test_directory).unwrap();
|
||||
|
||||
// Attempt to initialize a package at the `test_directory`
|
||||
assert!(Package::initialize(TEST_PACKAGE_NAME, true, &test_directory, None).is_err());
|
||||
|
||||
// Ensure package is not initialized at the `test_directory`
|
||||
assert!(!Package::is_initialized(TEST_PACKAGE_NAME, true, &test_directory));
|
||||
assert!(!Package::is_initialized(TEST_PACKAGE_NAME, &test_directory));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -109,25 +83,17 @@ fn initialize_fails_with_existing_input_file() {
|
||||
let test_directory = test_dir();
|
||||
|
||||
// Ensure a package can be initialized at the `test_directory`
|
||||
assert!(Package::can_initialize(TEST_PACKAGE_NAME, false, &test_directory));
|
||||
assert!(Package::can_initialize(TEST_PACKAGE_NAME, &test_directory));
|
||||
|
||||
// Manually add an inputs directory and an input file to the `test_directory`
|
||||
InputsDirectory::create(&test_directory).unwrap();
|
||||
InputFile::new(TEST_PACKAGE_NAME).write_to(&test_directory).unwrap();
|
||||
|
||||
// Attempt to initialize a package at the `test_directory`
|
||||
assert!(
|
||||
Package::initialize(
|
||||
TEST_PACKAGE_NAME,
|
||||
false,
|
||||
&test_directory,
|
||||
Some(String::from("test_user"))
|
||||
)
|
||||
.is_err()
|
||||
);
|
||||
assert!(Package::initialize(TEST_PACKAGE_NAME, &test_directory, Some(String::from("test_user"))).is_err());
|
||||
|
||||
// Ensure package is not initialized at the `test_directory`
|
||||
assert!(!Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory));
|
||||
assert!(!Package::is_initialized(TEST_PACKAGE_NAME, &test_directory));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -135,17 +101,17 @@ fn initialize_fails_with_existing_state_file() {
|
||||
let test_directory = test_dir();
|
||||
|
||||
// Ensure a package can be initialized at the `test_directory`
|
||||
assert!(Package::can_initialize(TEST_PACKAGE_NAME, false, &test_directory));
|
||||
assert!(Package::can_initialize(TEST_PACKAGE_NAME, &test_directory));
|
||||
|
||||
// Manually add an inputs directory and a state file to the `test_directory`
|
||||
InputsDirectory::create(&test_directory).unwrap();
|
||||
StateFile::new(TEST_PACKAGE_NAME).write_to(&test_directory).unwrap();
|
||||
|
||||
// Attempt to initialize a package at the `test_directory`
|
||||
assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory, None).is_err());
|
||||
assert!(Package::initialize(TEST_PACKAGE_NAME, &test_directory, None).is_err());
|
||||
|
||||
// Ensure package is not initialized at the `test_directory`
|
||||
assert!(!Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory));
|
||||
assert!(!Package::is_initialized(TEST_PACKAGE_NAME, &test_directory));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -153,15 +119,15 @@ fn initialize_fails_with_existing_main_file() {
|
||||
let test_directory = test_dir();
|
||||
|
||||
// Ensure a package can be initialized at the `test_directory`
|
||||
assert!(Package::can_initialize(TEST_PACKAGE_NAME, false, &test_directory));
|
||||
assert!(Package::can_initialize(TEST_PACKAGE_NAME, &test_directory));
|
||||
|
||||
// Manually add a source directory and a main file to the `test_directory`
|
||||
SourceDirectory::create(&test_directory).unwrap();
|
||||
MainFile::new(TEST_PACKAGE_NAME).write_to(&test_directory).unwrap();
|
||||
|
||||
// Attempt to initialize a package at the `test_directory`
|
||||
assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory, None).is_err());
|
||||
assert!(Package::initialize(TEST_PACKAGE_NAME, &test_directory, None).is_err());
|
||||
|
||||
// Ensure package is not initialized at the `test_directory`
|
||||
assert!(!Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory));
|
||||
assert!(!Package::is_initialized(TEST_PACKAGE_NAME, &test_directory));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user