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

Re-structure into combined lib & bin project #11

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all 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
13 changes: 9 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
[package]
name = "fishy"
version = "0.1.0"
authors = [
"adz <[email protected]>",
"sandreae <[email protected]>",
]
authors = ["adz <[email protected]>", "sandreae <[email protected]>"]
edition = "2021"
description = "Create, manage and deploy p2panda schemas"
repository = "https://github.com/p2panda/fishy"
license = "AGPL-3.0-or-later"
readme = "README.md"

[[bin]]
name = "fishy"
path = "src/main.rs"

[lib]
name = "fishy"
path = "src/lib/lib.rs"

[profile.release]
strip = true
opt-level = "z"
Expand Down
25 changes: 8 additions & 17 deletions src/commands/build/mod.rs → src/commands/build.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,19 @@
// SPDX-License-Identifier: AGPL-3.0-or-later

mod current;
mod diff;
mod executor;
mod previous;
mod print;
mod write;

use std::path::PathBuf;

use anyhow::{bail, Context, Result};
use dialoguer::Confirm;
use fishy::build::{
execute_plan, get_current_schemas, get_diff, get_previous_schemas, write_to_lock_file,
};
use fishy::lock_file::LockFile;
use fishy::schema_file::SchemaFile;
use fishy::utils::files::absolute_path;
use fishy::utils::key_pair;
use p2panda_rs::test_utils::memory_store::MemoryStore;

use crate::commands::build::current::get_current_schemas;
use crate::commands::build::diff::get_diff;
use crate::commands::build::executor::execute_plan;
use crate::commands::build::previous::get_previous_schemas;
use crate::commands::build::print::print_plan;
use crate::commands::build::write::write_to_lock_file;
use crate::lock_file::LockFile;
use crate::schema_file::SchemaFile;
use crate::utils::files::absolute_path;
use crate::utils::key_pair;
use crate::utils::print::print_plan;
use crate::utils::terminal::{print_title, print_variable};

/// Automatically creates and signs p2panda data from a key pair and the defined schemas.
Expand Down
94 changes: 8 additions & 86 deletions src/commands/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,13 @@

use std::path::PathBuf;

use anyhow::{anyhow, bail, Context, Result};
use gql_client::Client;
use anyhow::{bail, Context, Result};
use fishy::lock_file::LockFile;
use fishy::Client;
use indicatif::ProgressBar;
use p2panda_rs::entry::decode::decode_entry;
use p2panda_rs::entry::traits::AsEntry;
use p2panda_rs::entry::{LogId, SeqNum};
use p2panda_rs::hash::Hash;
use serde::Deserialize;

use crate::lock_file::LockFile;
use crate::utils::files::absolute_path;
use crate::utils::terminal::{print_title, print_variable};
use fishy::utils::files::absolute_path;

/// Deploy created schemas on a node.
pub async fn deploy(lock_path: PathBuf, endpoint: &str) -> Result<()> {
Expand All @@ -27,7 +22,7 @@ pub async fn deploy(lock_path: PathBuf, endpoint: &str) -> Result<()> {
lock_path.display()
))?;

let commits = lock_file.commits.unwrap_or(Vec::new());
let commits = lock_file.commits();
if commits.is_empty() {
bail!("No data given to deploy to node. Please run `update` command first.");
}
Expand All @@ -41,61 +36,12 @@ pub async fn deploy(lock_path: PathBuf, endpoint: &str) -> Result<()> {
let client = Client::new(endpoint);

for commit in commits {
let entry = decode_entry(&commit.entry).unwrap();
let published = client.publish(commit).await?;

let query = format!(
r#"
{{
nextArgs(publicKey: "{}", viewId: "{}") {{
logId
seqNum
skiplink
backlink
}}
}}
"#,
entry.public_key(),
commit.entry_hash,
);

let response = client.query_unwrap::<NextArgsResponse>(&query).await;

if let Ok(result) = response {
let args = result.next_args;

if entry.log_id() != &args.log_id {
bail!("Inconsistency between local commits and node detected");
}

// Check if node already knows about this commit
if entry.seq_num() < &args.seq_num {
skipped += 1;
progress.inc(1);

// Skip this one
continue;
}
if !published {
skipped += 1;
}

let query = format!(
r#"
mutation Publish {{
publish(entry: "{}", operation: "{}") {{
logId
seqNum
skiplink
backlink
}}
}}
"#,
commit.entry, commit.operation
);

client
.query_unwrap::<PublishResponse>(&query)
.await
.map_err(|err| anyhow!("GraphQL request to node failed: {err}"))?;

progress.inc(1);
}

Expand All @@ -113,27 +59,3 @@ pub async fn deploy(lock_path: PathBuf, endpoint: &str) -> Result<()> {

Ok(())
}

#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
#[allow(dead_code)]
struct NextArguments {
log_id: LogId,
seq_num: SeqNum,
skiplink: Option<Hash>,
backlink: Option<Hash>,
}

/// GraphQL response for `nextArgs` query.
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct NextArgsResponse {
next_args: NextArguments,
}

#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
#[allow(dead_code)]
struct PublishResponse {
publish: NextArguments,
}
4 changes: 2 additions & 2 deletions src/commands/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ use std::path::{Path, PathBuf};

use anyhow::{bail, Result};
use dialoguer::Input;
use fishy::utils::files::{absolute_path, write_file};
use fishy::utils::key_pair::write_key_pair;
use p2panda_rs::identity::KeyPair;
use p2panda_rs::schema::validate::validate_name;

use crate::constants::{PRIVATE_KEY_FILE_NAME, SCHEMA_FILE_NAME};
use crate::utils::files::{absolute_path, write_file};
use crate::utils::key_pair::write_key_pair;
use crate::utils::terminal::{print_title, print_variable};

/// Initialises all files for a new fishy project in a given folder.
Expand Down
2 changes: 1 addition & 1 deletion src/commands/build/current.rs → src/lib/build/current.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub fn get_current_schemas(schema_file: &SchemaFile) -> Result<Vec<CurrentSchema
schema_file
.iter()
.map(|(schema_name, schema_definition)| {
if schema_definition.fields.len() == 0 {
if schema_definition.fields.is_empty() {
bail!("Schema {schema_name} does not contain any fields");
}

Expand Down
File renamed without changes.
File renamed without changes.
14 changes: 14 additions & 0 deletions src/lib/build/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: AGPL-3.0-or-later

mod current;
mod diff;
mod executor;
mod previous;
mod write;

pub use current::get_current_schemas;
pub use diff::{get_diff, FieldTypeDiff};
pub use executor::{execute_plan, Plan};
pub use previous::get_previous_schemas;
pub use previous::PreviousSchemas;
pub use write::write_to_lock_file;
5 changes: 1 addition & 4 deletions src/commands/build/previous.rs → src/lib/build/previous.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,8 @@ pub async fn get_previous_schemas(
store: &MemoryStore,
lock_file: &LockFile,
) -> Result<PreviousSchemas> {
// Sometimes `commits` is not defined in the .toml file, set an empty array as a fallback
let commits = lock_file.commits.clone().unwrap_or_default();

// Publish every commit in our temporary, in-memory "node" to materialize schema documents
for commit in commits {
for commit in lock_file.commits() {
// Check entry hash integrity
if commit.entry_hash != commit.entry.hash() {
bail!(
Expand Down
8 changes: 2 additions & 6 deletions src/commands/build/write.rs → src/lib/build/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,13 @@ use crate::utils::files::{self};
/// Write commits to lock file.
pub fn write_to_lock_file(
mut new_commits: Vec<Commit>,
mut lock_file: LockFile,
lock_file: LockFile,
lock_path: PathBuf,
) -> Result<()> {
// Add new commits to the existing ones
let applied_commits_count = new_commits.len();
let mut commits: Vec<Commit> = Vec::new();

if let Some(current_commits) = lock_file.commits.as_mut() {
commits.append(current_commits);
}

let mut commits: Vec<Commit> = lock_file.commits();
commits.append(&mut new_commits);

// Write everything to .toml file
Expand Down
99 changes: 99 additions & 0 deletions src/lib/client.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// SPDX-License-Identifier: AGPL-3.0-or-later

use anyhow::{anyhow, bail, Result};
use gql_client::Client as GQLClient;
use p2panda_rs::entry::decode::decode_entry;
use p2panda_rs::entry::traits::AsEntry;
use p2panda_rs::entry::{LogId, SeqNum};
use p2panda_rs::hash::Hash;
use serde::Deserialize;

use crate::lock_file::Commit;

#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
#[allow(dead_code)]
struct NextArguments {
log_id: LogId,
seq_num: SeqNum,
skiplink: Option<Hash>,
backlink: Option<Hash>,
}

/// GraphQL response for `nextArgs` query.
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct NextArgsResponse {
next_args: NextArguments,
}

#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
#[allow(dead_code)]
struct PublishResponse {
publish: NextArguments,
}

pub struct Client(GQLClient);

impl Client {
pub fn new(endpoint: &str) -> Self {
Self(GQLClient::new(endpoint))
}

pub async fn publish(&self, commit: Commit) -> Result<bool> {
let entry = decode_entry(&commit.entry).unwrap();

let query = format!(
r#"
{{
nextArgs(publicKey: "{}", viewId: "{}") {{
logId
seqNum
skiplink
backlink
}}
}}
"#,
entry.public_key(),
commit.entry_hash,
);

let response = self.0.query_unwrap::<NextArgsResponse>(&query).await;

if let Ok(result) = response {
let args = result.next_args;

if entry.log_id() != &args.log_id {
bail!("Inconsistency between local commits and node detected");
}

// Check if node already knows about this commit
if entry.seq_num() < &args.seq_num {
// Skip this one
return Ok(false);
}
}

let query = format!(
r#"
mutation Publish {{
publish(entry: "{}", operation: "{}") {{
logId
seqNum
skiplink
backlink
}}
}}
"#,
commit.entry, commit.operation
);

self.0
.query_unwrap::<PublishResponse>(&query)
.await
.map_err(|err| anyhow!("GraphQL request to node failed: {err}"))?;

Ok(true)
}
}
7 changes: 7 additions & 0 deletions src/lib/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
pub mod build;
mod client;
pub mod lock_file;
pub mod schema_file;
pub mod utils;

pub use client::Client;
Loading