Skip to content

Commit

Permalink
Merge pull request #248 from perspect3vism/release-0.2.13
Browse files Browse the repository at this point in the history
  • Loading branch information
lucksus authored Feb 15, 2023
2 parents d5766a5 + a008afd commit 1c9e3bf
Show file tree
Hide file tree
Showing 27 changed files with 513 additions and 167 deletions.
30 changes: 30 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,36 @@
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
This project _loosely_ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). More specifically:

## unreleased

### Added

### Changed

### Deprecated

### Removed

### Fixed

## [0.2.13] - 15/02/2013

### Added
- Expression "create", "get" and "get-raw" added to cli and rust-client [PR#159](https://github.com/perspect3vism/ad4m/pull/159)

### Changed
- CLI: `ad4m languages generate-boostrap` is now availabel under `ad4m dev generate-bootstrap`
- Default bootstrap-seed updated

### Deprecated

### Removed

### Fixed
- Bootstrap seed creation working with cli: `ad4m dev generate-bootstrap` [PR#247](https://github.com/perspect3vism/ad4m/pull/247)



## [0.2.12-patch-1] - 14/02/2023

### Changed
Expand Down
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ad4m"
version = "0.2.12-patch-1"
version = "0.2.13"
edition = "2021"
authors = ["Nicolas Luck <[email protected]>"]
description = "A command-line interface to AD4M (i.e. the AD4M executor) - https://ad4m.dev"
Expand All @@ -12,7 +12,7 @@ documentation = "https://docs.ad4m.dev"
readme = "README.md"

[dependencies]
ad4m-client = { path = "../rust-client", version = "0.2.12-patch-1" }
ad4m-client = { path = "../rust-client", version = "0.2.13" }
anyhow = "1.0.65"
clap = { version = "4.0.8", features = ["derive"] }
futures = "0.3"
Expand Down
17 changes: 11 additions & 6 deletions cli/src/bootstrap_publish.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use ad4m_client::Ad4mClient;
use anyhow::Result;
use clap::Parser;
use colour::{blue_ln, green_ln};
use serde::{Deserialize, Serialize};
use std::io::{BufRead, BufReader};
Expand All @@ -8,8 +8,6 @@ use std::process::exit;
use std::sync::mpsc::Sender;
use std::{fs, process::Stdio};

use crate::{get_ad4m_client, ClapApp};

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct SeedProto {
#[serde(rename = "languageLanguageRef")]
Expand Down Expand Up @@ -118,15 +116,22 @@ pub async fn start_publishing(
seed_proto: SeedProto,
language_language_bundle: String,
) {
let ad4m_client = get_ad4m_client(&ClapApp::parse())
.await
.expect("Could not get ad4m client");
let ad4m_client = Ad4mClient::new(
"http://localhost:4000/graphql".to_string(),
"".to_string()
);

let agent = ad4m_client
.agent
.unlock(passphrase)
.await
.expect("could not unlock agent");

if let Some(error) = agent.error {
println!("Error unlocking agent: {}", error);
exit(1);
}

green_ln!("Unlocked agent\n");

let mut languages = vec![];
Expand Down
125 changes: 125 additions & 0 deletions cli/src/dev.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@

use anyhow::{Result};
use clap::Subcommand;
use colour::{self, blue_ln, green_ln};
use std::fs;
use std::sync::mpsc::channel;

use crate::bootstrap_publish::*;

#[derive(Debug, Subcommand)]
pub enum DevFunctions {
/// Generate bootstrap seed from a local prototype JSON file declaring languages to be published
GenerateBootstrap {
agent_path: String,
passphrase: String,
ad4m_host_path: String,
seed_proto: String,
},
}

pub async fn run(command: DevFunctions) -> Result<()> {
match command {
DevFunctions::GenerateBootstrap {
agent_path,
passphrase,
ad4m_host_path,
seed_proto,
} => {
green_ln!(
"Attempting to generate a new bootstrap seed using ad4m-host path: {:?} and agent path: {:?}\n",
ad4m_host_path,
agent_path
);

//Load the seed proto first so we know that works before making new agent path
let seed_proto = fs::read_to_string(seed_proto)?;
let seed_proto: SeedProto = serde_json::from_str(&seed_proto)?;
green_ln!("Loaded seed prototype file!\n");

//Create a new ~/.ad4m-publish path with agent.json file supplied
let data_path = dirs::home_dir()
.expect("Could not get home directory")
.join(".ad4m-publish");
let data_path_files = std::fs::read_dir(&data_path);
if data_path_files.is_ok() {
fs::remove_dir_all(&data_path)?;
}
//Create the ad4m directory
fs::create_dir(&data_path)?;
let ad4m_data_path = data_path.join("ad4m");
fs::create_dir(&ad4m_data_path)?;
let data_data_path = data_path.join("data");
fs::create_dir(&data_data_path)?;

//Read the agent file
let agent_file = fs::read_to_string(agent_path)?;
//Copy the agent file to correct directory
fs::write(ad4m_data_path.join("agent.json"), agent_file)?;
fs::write(data_data_path.join("DIDCache.json"), String::from("{}"))?;
green_ln!("Publishing agent directory setup\n");

green_ln!("Creating temporary bootstrap seed for publishing purposes...\n");
let lang_lang_source = fs::read_to_string(&seed_proto.language_language_ref)?;
let temp_bootstrap_seed = BootstrapSeed {
trusted_agents: vec![],
known_link_languages: vec![],
language_language_bundle: lang_lang_source.clone(),
direct_message_language: String::from(""),
agent_language: String::from(""),
perspective_language: String::from(""),
neighbourhood_language: String::from(""),
};
let temp_publish_bootstrap_path = data_path.join("publishing_bootstrap.json");
fs::write(
&temp_publish_bootstrap_path,
serde_json::to_string(&temp_bootstrap_seed)?,
)?;

//start ad4m-host with publishing bootstrap
let ad4m_host_init = std::process::Command::new(&ad4m_host_path)
.arg("init")
.arg("--networkBootstrapSeed")
.arg(&temp_publish_bootstrap_path)
.arg("--dataPath")
.arg(&data_path)
.arg("--overrideConfig")
.output()?;

blue_ln!(
"ad4m-host init output: {}\n",
String::from_utf8_lossy(&ad4m_host_init.stdout)
);

green_ln!(
"Starting publishing with bootstrap path: {}\n",
temp_publish_bootstrap_path.to_str().unwrap()
);

let (tx, rx) = channel();
serve_ad4m_host(ad4m_host_path, data_path, tx)?;

for line in &rx {
println!("{}", line);
if line.contains("GraphQL server started, Unlock the agent to start holohchain") {
green_ln!("AD4M Host ready for publishing\n");
//Spawn in a new thread so we can continue reading logs in loop below, whilst publishing is happening
tokio::spawn(async move {
start_publishing(
passphrase.clone(),
seed_proto.clone(),
lang_lang_source.clone(),
)
.await;
});
break;
}
}

for line in rx {
println!("{}", line);
}
}
};
Ok(())
}
67 changes: 67 additions & 0 deletions cli/src/expression.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
use ad4m_client::{Ad4mClient, expressions::expression};
use anyhow::{Result, bail};
use clap::Subcommand;
use serde_json::Value;

#[derive(Debug, Subcommand)]
pub enum ExpressionFunctions {
Create {
language_address: String,
content: String,
},
Get {
url: String,
},
GetRaw {
url: String,
},
}

pub async fn run(ad4m_client: Ad4mClient, command: ExpressionFunctions) -> Result<()> {
match command {
ExpressionFunctions::Create {
language_address,
content,
} => {
let content = serde_json::from_str::<Value>(&content).unwrap_or_else(|_| {
serde_json::from_str::<Value>(&format!("\"{}\"", content)).unwrap()
});
let expression_url = ad4m_client
.expressions
.expression_create(language_address, content)
.await?;
println!("Expression created with url: {}", expression_url);
}
ExpressionFunctions::Get { url } => {
let maybe_content: Option<expression::ExpressionExpression> = ad4m_client.expressions.expression(url.clone()).await?;
match maybe_content {
Some(content) => {
println!("author: {}", content.author);
println!("timestamp: {}", content.timestamp);
if content.proof.valid.unwrap_or(false) {
println!("signature: ✅");
} else {
println!("signature: ❌");
}
println!("data: {}", content.data)
}
None => println!("No expression found at url: {}", url),
}
}

ExpressionFunctions::GetRaw { url } => {
let maybe_content: Option<expression::ExpressionExpression> = ad4m_client.expressions.expression(url.clone()).await?;
match maybe_content {
Some(content) => {
if let Ok(Value::String(content)) = serde_json::from_str::<Value>(&content.data) {
println!("{}", &content);
} else {
println!("{}", content.data);
}
}
None => bail!("No expression found at url: {}", url),
}
}
};
Ok(())
}
Loading

0 comments on commit 1c9e3bf

Please sign in to comment.