Skip to content

Commit

Permalink
chore: Backport and release 0.4000.0-rc.1 (#396)
Browse files Browse the repository at this point in the history
* Bump crate version

* feat: Create links from/to `ExternalHash` (#380)

* add ExternalHash field types and option to target this type when scaffolding a link-type

* ensure external hash is imported in type declarations

* feat: create links from/to AnyLinkableHash

* Add AnyLinkablehHash field type templates and add to reserved words

* fix failed to resolve errors

* improve checking for reserved keywords

* fix invalid link-type delete method in test template

* simplify reserved_words hashsets

* update cli

* Extend reserved keywords to check for javascript keywords

* Update AnyLinkableHash sample value

* Extend reserved words check tests

* fix AnyLinkableHash link-type tests

* Fix AnyLinkableHash link-type tests and remove redundant AND/OR hbs
helpers

* update inner_choose_referenceable

* /AnyLinkableHash/ExternalHash

* Update invalid serserved word error message

* Refactor entry/link type utils

* Add some context to the [None] option when scaffolding a link-type

* /AnyLinkableHash/ExternalHash in link-type template

* Fix option placement

* Prevent UI from getting generated where the base type of a link is an
ExternalHash

* ExternalHash links can be bidirectional

* Only skip ui if to_referenceable is some and the field_type is of
ExternalHash

* Remove unnecessary into call in delete link function

* Fix rustfmt ci failure

* Fix missing conversion

* Fix react link-type template

* feat: Improve `hc-scaffold entry-type` developer experience (#383)

* refactor enum type selection; add option to restart field type
selection; refactor FieldType parsing

* Improve EntryTypeReference parsing

* Improve parse_enum parsing logic

* Update field_type parsing logic

* fix: Optimize nix flake (#384)

* optimize nix flake

* Supress clippy warnings

* Nix flake update
  • Loading branch information
c12i authored Oct 21, 2024
1 parent 9c901ca commit 920cb19
Show file tree
Hide file tree
Showing 33 changed files with 908 additions and 660 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
edition = "2021"
name = "holochain_scaffolding_cli"
version = "0.4000.0-rc.0"
version = "0.4000.0-rc.1"
description = "CLI to easily generate and modify holochain apps"
license = "CAL-1.0"
homepage = "https://developer.holochain.org"
Expand Down
24 changes: 12 additions & 12 deletions flake.lock

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

18 changes: 8 additions & 10 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,15 @@ impl HcScaffold {
let template_type = self.get_template_type(&current_dir, scaffold_config.as_ref())?;

match self.command {
HcScaffoldCommand::WebApp(web_app) => web_app.run(&template_type).await?,
HcScaffoldCommand::Template(template) => template.run(&template_type)?,
HcScaffoldCommand::Dna(dna) => dna.run(&template_type)?,
HcScaffoldCommand::Zome(zome) => zome.run(&template_type)?,
HcScaffoldCommand::EntryType(entry_type) => entry_type.run(&template_type)?,
HcScaffoldCommand::LinkType(link_type) => link_type.run(&template_type)?,
HcScaffoldCommand::Collection(collection) => collection.run(&template_type)?,
HcScaffoldCommand::Example(example) => example.run(&template_type).await?,
HcScaffoldCommand::WebApp(web_app) => web_app.run(&template_type).await,
HcScaffoldCommand::Template(template) => template.run(&template_type),
HcScaffoldCommand::Dna(dna) => dna.run(&template_type),
HcScaffoldCommand::Zome(zome) => zome.run(&template_type),
HcScaffoldCommand::EntryType(entry_type) => entry_type.run(&template_type),
HcScaffoldCommand::LinkType(link_type) => link_type.run(&template_type),
HcScaffoldCommand::Collection(collection) => collection.run(&template_type),
HcScaffoldCommand::Example(example) => example.run(&template_type).await,
}

Ok(())
}

fn get_template_type(
Expand Down
4 changes: 2 additions & 2 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ pub enum ScaffoldError {
#[error("Folder already exists: {0}")]
FolderAlreadyExists(PathBuf),

#[error("Invalid reserved word: {0}")]
InvalidReservedWord(String),
#[error("Invalid use of reserved {context} keyword '{word}' in this context.")]
InvalidReservedWord { context: String, word: String },

#[error("Invalid path {0}: {1}")]
InvalidPath(PathBuf, String),
Expand Down
144 changes: 110 additions & 34 deletions src/reserved_words.rs
Original file line number Diff line number Diff line change
@@ -1,44 +1,120 @@
use std::collections::HashSet;

use crate::error::{ScaffoldError, ScaffoldResult};

const RESERVED_WORDS: [&str; 27] = [
"type",
/// Returns an error if the given string is invalid due to it being a reserved word
pub fn check_for_reserved_keywords(string_to_check: &str) -> ScaffoldResult<()> {
let reserved_holochain_words_set = HashSet::from(HOLOCHAIN_RESERVED_KEYWORDS);
let reserved_rust_words_set = HashSet::from(RUST_RESERVED_KEYWORDS);
let reserved_javascript_words_set = HashSet::from(JAVASCRIPT_RESERVED_KEYWORDS);

if reserved_holochain_words_set.contains(string_to_check.to_ascii_lowercase().as_str()) {
return Err(ScaffoldError::InvalidReservedWord {
context: "holochain".to_string(),
word: string_to_check.to_string(),
});
}

if reserved_rust_words_set.contains(string_to_check.to_ascii_lowercase().as_str()) {
return Err(ScaffoldError::InvalidReservedWord {
context: "rust".to_string(),
word: string_to_check.to_string(),
});
}

if reserved_javascript_words_set.contains(string_to_check.to_ascii_lowercase().as_str()) {
return Err(ScaffoldError::InvalidReservedWord {
context: "javascript".to_string(),
word: string_to_check.to_string(),
});
}

Ok(())
}

const HOLOCHAIN_RESERVED_KEYWORDS: [&str; 16] = [
"role",
"enum",
"pub",
"fn",
"mod",
"struct",
"const",
"Option",
"Result",
"crate",
"hdi",
"hdk",
"return",
"if",
"action",
"entry",
"record",
"zome",
"dna",
"entrytype",
"entryhash",
"actionhash",
"agentpubkey",
"anylinkablehash",
"holohash",
"externalhash",
"call",
];

// <https://doc.rust-lang.org/reference/keywords.html>
const RUST_RESERVED_KEYWORDS: [&str; 50] = [
"as", "break", "const", "continue", "crate", "else", "enum", "extern", "false", "fn", "for",
"if", "impl", "in", "let", "loop", "match", "mod", "move", "mut", "pub", "ref", "return",
"self", "Self", "static", "struct", "super", "trait", "true", "type", "unsafe", "use", "where",
"while", "abstract", "async", "await", "become", "box", "do", "final", "macro", "override",
"priv", "try", "typeof", "unsized", "virtual", "yield",
];

// <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#reserved_words>
const JAVASCRIPT_RESERVED_KEYWORDS: [&str; 35] = [
"break",
"case",
"catch",
"class",
"const",
"continue",
"debugger",
"default",
"delete",
"do",
"else",
"match",
"Action",
"Entry",
"Record",
"Zome",
"Dna",
"EntryType",
"EntryHash",
"ActionHash",
"AgentPubKey",
"Call",
"export",
"extends",
"false",
"finally",
"for",
"function",
"if",
"import",
"in",
"instanceof",
"new",
"null",
"return",
"super",
"switch",
"this",
"throw",
"true",
"try",
"typeof",
"var",
"void",
"while",
"with",
];

/// Returns an error if the given string is invalid due to it being a reserved word
pub fn check_for_reserved_words(string_to_check: &str) -> ScaffoldResult<()> {
if RESERVED_WORDS
.iter()
.any(|w| string_to_check.eq_ignore_ascii_case(w))
{
return Err(ScaffoldError::InvalidReservedWord(
string_to_check.to_string(),
));
#[cfg(test)]
mod tests {
use super::*;

#[test]
fn check_for_reserved_keywords_works() {
let valid = check_for_reserved_keywords("Value");
assert!(valid.is_ok());

let invalid = check_for_reserved_keywords("static");
assert!(invalid.is_err());

let invalid = check_for_reserved_keywords("EntryType");
assert!(invalid.is_err());

let invalid = check_for_reserved_keywords("new");
assert!(invalid.is_err());
}
Ok(())
}
4 changes: 2 additions & 2 deletions src/scaffold/collection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use serde::Serialize;
use crate::{
error::{ScaffoldError, ScaffoldResult},
file_tree::FileTree,
reserved_words::check_for_reserved_words,
reserved_words::check_for_reserved_keywords,
templates::{collection::scaffold_collection_templates, ScaffoldedTemplate},
};

Expand Down Expand Up @@ -74,7 +74,7 @@ pub fn scaffold_collection(
no_ui: bool,
no_spec: bool,
) -> ScaffoldResult<ScaffoldedTemplate> {
check_for_reserved_words(collection_name)?;
check_for_reserved_keywords(collection_name)?;

let all_entries = get_all_entry_types(&integrity_zome_file_tree)?.ok_or(
ScaffoldError::NoEntryTypesDefFoundForIntegrityZome(
Expand Down
4 changes: 2 additions & 2 deletions src/scaffold/dna.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
dir_exists, file_content, find_files_by_name, insert_file, insert_file_tree_in_dir,
FileTree,
},
reserved_words::check_for_reserved_words,
reserved_words::check_for_reserved_keywords,
templates::{dna::scaffold_dna_templates, ScaffoldedTemplate},
utils::choose_directory_path,
};
Expand Down Expand Up @@ -168,7 +168,7 @@ pub fn scaffold_dna(
template_file_tree: &FileTree,
dna_name: &str,
) -> ScaffoldResult<ScaffoldedTemplate> {
check_for_reserved_words(dna_name)?;
check_for_reserved_keywords(dna_name)?;

let new_dna_file_tree: FileTree = dir! {
"zomes" => dir! {
Expand Down
10 changes: 5 additions & 5 deletions src/scaffold/entry_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::{ffi::OsString, path::PathBuf};

use crate::{
file_tree::FileTree,
reserved_words::check_for_reserved_words,
reserved_words::check_for_reserved_keywords,
templates::{entry_type::scaffold_entry_type_templates, ScaffoldedTemplate},
};

Expand Down Expand Up @@ -47,7 +47,7 @@ pub fn scaffold_entry_type(
no_ui: bool,
no_spec: bool,
) -> ScaffoldResult<ScaffoldedTemplate> {
check_for_reserved_words(name)?;
check_for_reserved_keywords(name)?;

if no_ui {
let warning_text = r#"
Expand Down Expand Up @@ -139,13 +139,13 @@ inadvertently reference or expect elements from the skipped entry type."#
let coordinator_zome = match coordinator_zomes_for_integrity.len() {
0 => Err(ScaffoldError::NoCoordinatorZomesFoundForIntegrityZome(
zome_file_tree.dna_file_tree.dna_manifest.name(),
zome_file_tree.zome_manifest.name.0.to_string(),
zome_file_tree.zome_manifest.name.to_string(),
)),
1 => Ok(coordinator_zomes_for_integrity[0].clone()),
_ => {
let names: Vec<String> = coordinator_zomes_for_integrity
.iter()
.map(|z| z.name.0.to_string())
.map(|z| z.name.to_string())
.collect();
let selection = Select::with_theme(&ColorfulTheme::default())
.with_prompt("Which coordinator zome should the CRUD functions be scaffolded in?")
Expand Down Expand Up @@ -217,7 +217,7 @@ fn check_field_definitions(
.iter()
.filter_map(|f| f.linked_from.clone())
.filter_map(|t| match t {
Referenceable::Agent { .. } => None,
Referenceable::Agent { .. } | Referenceable::ExternalHash { .. } => None,
Referenceable::EntryType(et) => Some(et),
})
.collect();
Expand Down
4 changes: 2 additions & 2 deletions src/scaffold/entry_type/coordinator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,10 @@ pub fn add_crud_functions_to_coordinator(
}

fn no_update_read_handler(entry_def: &EntryDefinition) -> TokenStream {
let hash_type = entry_def.referenceable().hash_type().to_string();
let hash_type = entry_def.referenceable().field_type().to_string();
let snake_entry_def_name = entry_def.name.to_case(Case::Snake);

match entry_def.referenceable().hash_type() {
match entry_def.referenceable().field_type() {
FieldType::ActionHash => {
let get_entry_def_function_name = format_ident!("get_{snake_entry_def_name}");
let entry_hash_param = format_ident!("{snake_entry_def_name}_hash");
Expand Down
Loading

0 comments on commit 920cb19

Please sign in to comment.