Skip to content

Commit

Permalink
refactor: clean up duplicated templates (holochain#313)
Browse files Browse the repository at this point in the history
* derive common templates

* derive a scaffold config module and move config related code to it

* remove field types from generic templates

* delete repeated templates

* fix clippy warnings

* further trim down repeated templates
  • Loading branch information
c12i committed Jul 17, 2024
1 parent d9ba951 commit baa05a7
Show file tree
Hide file tree
Showing 514 changed files with 183 additions and 3,456 deletions.
107 changes: 57 additions & 50 deletions src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use crate::error::ScaffoldError;
use crate::error::{ScaffoldError, ScaffoldResult};
use crate::file_tree::{build_file_tree, file_content, load_directory_into_memory, FileTree};
use crate::scaffold::app::cargo::exec_metadata;
use crate::scaffold::app::git::setup_git_environment;
use crate::scaffold::app::nix::setup_nix_developer_environment;
use crate::scaffold::app::AppFileTree;
use crate::scaffold::collection::{scaffold_collection, CollectionType};
use crate::scaffold::config::ScaffoldConfig;
use crate::scaffold::dna::{scaffold_dna, DnaFileTree};
use crate::scaffold::entry_type::crud::{parse_crud, Crud};
use crate::scaffold::entry_type::definitions::{
Expand All @@ -31,8 +32,6 @@ use colored::Colorize;
use convert_case::Case;
use dialoguer::theme::ColorfulTheme;
use dialoguer::Input;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::ffi::OsString;
use std::path::{Path, PathBuf};
use std::str::FromStr;
Expand Down Expand Up @@ -213,52 +212,9 @@ pub enum HcScaffoldCommand {
impl HcScaffold {
pub async fn run(self) -> anyhow::Result<()> {
let current_dir = std::env::current_dir()?;
let template_config = get_template_config(&current_dir)?;
let template = match (&template_config, &self.template) {
(Some(config), Some(template)) if &config.template != template => {
return Err(ScaffoldError::InvalidArguments(format!(
"The value {} passed with `--template` does not match the template the web-app was scaffolded with: {}",
template.italic(),
config.template.italic(),
)).into())
}
// Only read from config if the template is inbuilt and not a path
(Some(config), _) if !Path::new(&config.template).exists() => Some(&config.template),
(_, t) => t.as_ref(),
};

// Given a template either passed via the --template flag or retreived via the hcScaffold config,
// get the template file tree and the ui framework name or custom template path
let (template, template_file_tree) = match template {
Some(template) => match template.to_lowercase().as_str() {
"lit" | "svelte" | "vanilla" | "vue" | "react" | "headless" => {
let ui_framework = UiFramework::from_str(template)?;
(ui_framework.name(), ui_framework.template_filetree()?)
}
custom_template_path if Path::new(custom_template_path).exists() => {
let templates_dir = current_dir.join(PathBuf::from(custom_template_path));
(
custom_template_path.to_string(),
load_directory_into_memory(&templates_dir)?,
)
}
path => return Err(ScaffoldError::PathNotFound(PathBuf::from(path)).into()),
},
None => {
let ui_framework = match self.command {
HcScaffoldCommand::WebApp { .. } => UiFramework::choose()?,
HcScaffoldCommand::Example { ref example, .. } => match example {
Some(Example::HelloWorld) => UiFramework::Vanilla,
_ => UiFramework::choose_non_vanilla()?,
},
_ => {
let file_tree = load_directory_into_memory(&current_dir)?;
UiFramework::try_from(&file_tree)?
}
};
(ui_framework.name(), ui_framework.template_filetree()?)
}
};
let scaffold_config = ScaffoldConfig::from_package_json_path(&current_dir)?;
let (template, template_file_tree) =
self.get_template(&current_dir, scaffold_config.as_ref())?;

match self.command {
HcScaffoldCommand::WebApp {
Expand Down Expand Up @@ -311,7 +267,7 @@ impl HcScaffold {
holo_enabled,
)?;

let file_tree = write_scaffold_config(file_tree, &template)?;
let file_tree = ScaffoldConfig::write_to_package_json(file_tree, &template)?;

build_file_tree(dir! {&name => file_tree}, ".")?;

Expand Down Expand Up @@ -884,6 +840,8 @@ Add new collections for that entry type with:
next_instructions,
} = scaffold_example(file_tree, &template_file_tree, &example)?;

let file_tree = ScaffoldConfig::write_to_package_json(file_tree, &template)?;

build_file_tree(file_tree, &app_dir)?;

// set up nix
Expand All @@ -904,6 +862,55 @@ Add new collections for that entry type with:

Ok(())
}

fn get_template(
&self,
current_dir: &Path,
scaffold_config: Option<&ScaffoldConfig>,
) -> Result<(String, FileTree), ScaffoldError> {
let template = match (scaffold_config, &self.template) {
(Some(config), Some(template)) if &config.template != template => {
return Err(ScaffoldError::InvalidArguments(format!(
"The value {} passed with `--template` does not match the template the web-app was scaffolded with: {}",
template.italic(),
config.template.italic(),
)));
}
(Some(config), _) if !Path::new(&config.template).exists() => Some(&config.template),
(_, t) => t.as_ref(),
};

match template {
Some(template) => match template.to_lowercase().as_str() {
"lit" | "svelte" | "vanilla" | "vue" | "react" | "headless" => {
let ui_framework = UiFramework::from_str(template)?;
Ok((ui_framework.name(), ui_framework.template_filetree()?))
}
custom_template_path if Path::new(custom_template_path).exists() => {
let templates_dir = current_dir.join(custom_template_path);
Ok((
custom_template_path.to_string(),
load_directory_into_memory(&templates_dir)?,
))
}
path => Err(ScaffoldError::PathNotFound(PathBuf::from(path))),
},
None => {
let ui_framework = match &self.command {
HcScaffoldCommand::WebApp { .. } => UiFramework::choose()?,
HcScaffoldCommand::Example { ref example, .. } => match example {
Some(Example::HelloWorld) => UiFramework::Vanilla,
_ => UiFramework::choose_non_vanilla()?,
},
_ => {
let file_tree = load_directory_into_memory(current_dir)?;
UiFramework::try_from(&file_tree)?
}
};
Ok((ui_framework.name(), ui_framework.template_filetree()?))
}
}
}
}

#[derive(Debug, StructOpt)]
Expand Down
9 changes: 6 additions & 3 deletions src/file_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,9 +305,12 @@ pub fn create_dir_all(file_tree: &mut FileTree, path: &Path) -> ScaffoldResult<(
Ok(())
}

pub fn dir_to_file_tree(dir: &Dir<'_>) -> ScaffoldResult<FileTree> {
let flattened = walk_dir(dir);

pub fn template_dirs_to_file_tree(
ui_framework_template_dir: &Dir<'_>,
generic_template_dir: &Dir<'_>,
) -> ScaffoldResult<FileTree> {
let mut flattened = walk_dir(ui_framework_template_dir);
flattened.extend(walk_dir(generic_template_dir));
unflatten_file_tree(&flattened)
}

Expand Down
1 change: 1 addition & 0 deletions src/scaffold.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod app;
pub mod collection;
pub mod config;
pub mod dna;
pub mod entry_type;
pub mod example;
Expand Down
66 changes: 66 additions & 0 deletions src/scaffold/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
use std::{
fs,
path::{Path, PathBuf},
};

use serde::{Deserialize, Serialize};
use serde_json::Value;

use crate::{
error::ScaffoldResult,
file_tree::{map_file, FileTree},
};

#[derive(Debug, Deserialize, Serialize)]
pub struct ScaffoldConfig {
pub template: String,
}

impl ScaffoldConfig {
/// Gets template config written to the root `package.json` file when the hApp was
/// originally scaffolded
pub fn from_package_json_path<P: Into<PathBuf>>(path: P) -> ScaffoldResult<Option<Self>> {
let package_json_path = path.into().join("package.json");
let Ok(file) = fs::read_to_string(package_json_path) else {
return Ok(None);
};
let file = serde_json::from_str::<Value>(&file)?;
if let Some(config) = file.get("hcScaffold") {
let config = serde_json::from_value(config.to_owned())?;
Ok(Some(config))
} else {
Ok(None)
}
}

pub fn write_to_package_json(
mut web_app_file_tree: FileTree,
template: &str,
) -> ScaffoldResult<FileTree> {
if Path::new(template).exists() {
return Ok(web_app_file_tree);
}
let config = ScaffoldConfig {
template: template.to_owned(),
};
let package_json_path = PathBuf::from("package.json");
map_file(&mut web_app_file_tree, &package_json_path, |c| {
let original_content = c.clone();
let json = serde_json::from_str::<Value>(&c)?;
let json = match json {
Value::Object(mut o) => {
o.insert(
"hcScaffold".to_owned(),
serde_json::to_value(&config).unwrap(),
);
o
}
_ => return Ok(original_content),
};
let json = serde_json::to_value(json)?;
let json = serde_json::to_string_pretty(&json)?;
Ok(json)
})?;
Ok(web_app_file_tree)
}
}
23 changes: 15 additions & 8 deletions src/scaffold/web_app/uis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,22 @@ use std::{ffi::OsString, path::PathBuf, str::FromStr};

use crate::{
error::{ScaffoldError, ScaffoldResult},
file_tree::{dir_exists, dir_to_file_tree, file_exists, FileTree},
file_tree::{dir_exists, file_exists, template_dirs_to_file_tree, FileTree},
};

static LIT_TEMPLATES: Dir<'static> = include_dir!("$CARGO_MANIFEST_DIR/templates/lit");
static SVELTE_TEMPLATES: Dir<'static> = include_dir!("$CARGO_MANIFEST_DIR/templates/svelte");
static VUE_TEMPLATES: Dir<'static> = include_dir!("$CARGO_MANIFEST_DIR/templates/vue");
static VANILLA_TEMPLATES: Dir<'static> = include_dir!("$CARGO_MANIFEST_DIR/templates/vanilla");
static REACT_TEMPLATES: Dir<'static> = include_dir!("$CARGO_MANIFEST_DIR/templates/react");
static LIT_TEMPLATES: Dir<'static> =
include_dir!("$CARGO_MANIFEST_DIR/templates/ui-frameworks/lit");
static SVELTE_TEMPLATES: Dir<'static> =
include_dir!("$CARGO_MANIFEST_DIR/templates/ui-frameworks/svelte");
static VUE_TEMPLATES: Dir<'static> =
include_dir!("$CARGO_MANIFEST_DIR/templates/ui-frameworks/vue");
static VANILLA_TEMPLATES: Dir<'static> =
include_dir!("$CARGO_MANIFEST_DIR/templates/ui-frameworks/vanilla");
static REACT_TEMPLATES: Dir<'static> =
include_dir!("$CARGO_MANIFEST_DIR/templates/ui-frameworks/react");

static HEADLESS_TEMPLATE: Dir<'static> = include_dir!("$CARGO_MANIFEST_DIR/templates/headless");
static GENERIC_TEMPLATES: Dir<'static> = include_dir!("$CARGO_MANIFEST_DIR/templates/generic");

#[derive(Debug, Clone)]
pub enum UiFramework {
Expand All @@ -40,15 +47,15 @@ impl UiFramework {
}

pub fn template_filetree(&self) -> ScaffoldResult<FileTree> {
let dir = match self {
let ui_framework_dir = match self {
UiFramework::Lit => &LIT_TEMPLATES,
UiFramework::Vanilla => &VANILLA_TEMPLATES,
UiFramework::Svelte => &SVELTE_TEMPLATES,
UiFramework::Vue => &VUE_TEMPLATES,
UiFramework::React => &REACT_TEMPLATES,
UiFramework::Headless => &HEADLESS_TEMPLATE,
};
dir_to_file_tree(dir)
template_dirs_to_file_tree(ui_framework_dir, &GENERIC_TEMPLATES)
}

pub fn choose() -> ScaffoldResult<UiFramework> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
name: "test"
on:
# Trigger the workflow on push or pull request,
# but only for the main branch
push:
branches: [ main, develop ]
branches: [ main ]
pull_request:
branches: [ main, develop ]
branches: [ main ]

jobs:
testbuild:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

- name: Install nix
uses: cachix/install-nix-action@v18
uses: cachix/install-nix-action@v25
with:
install_url: https://releases.nixos.org/nix/nix-2.12.0/install
extra_nix_config: |
Expand All @@ -27,4 +25,3 @@ jobs:
- name: Install and test
run: |
nix develop --command bash -c "npm i && npm t"

Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
import { CallableCell } from '@holochain/tryorama';
import { NewEntryAction, ActionHash, Record, AppBundleSource, fakeActionHash, fakeAgentPubKey, fakeEntryHash, fakeDnaHash } from '@holochain/client';

Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,3 @@ export async function create{{pascal_case entry_type.name}}(cell: CallableCell,
payload: {{camel_case entry_type.name}} || await sample{{pascal_case entry_type.name}}(cell),
});
}

1 change: 1 addition & 0 deletions templates/generic/field-types/ActionHash/sample.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(await fakeActionHash())
1 change: 1 addition & 0 deletions templates/generic/field-types/ActionHash/type.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ActionHash
1 change: 1 addition & 0 deletions templates/generic/field-types/AgentPubKey/sample.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(await fakeAgentPubKey())
1 change: 1 addition & 0 deletions templates/generic/field-types/AgentPubKey/type.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
AgentPubKey
1 change: 1 addition & 0 deletions templates/generic/field-types/DnaHash/sample.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(await fakeDnaHash())
1 change: 1 addition & 0 deletions templates/generic/field-types/DnaHash/type.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DnaHash
1 change: 1 addition & 0 deletions templates/generic/field-types/EntryHash/sample.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(await fakeEntryHash())
1 change: 1 addition & 0 deletions templates/generic/field-types/EntryHash/type.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
EntryHash
1 change: 1 addition & 0 deletions templates/generic/field-types/Enum/default.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ type: '{{lookup field_type.variants 0}}' }
1 change: 1 addition & 0 deletions templates/generic/field-types/Enum/sample.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ type: '{{lookup field_type.variants 0}}' }
1 change: 1 addition & 0 deletions templates/generic/field-types/Enum/type.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{pascal_case field_type.label}}
1 change: 1 addition & 0 deletions templates/generic/field-types/String/sample.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"Lorem ipsum dolor sit amet, consectetur adipiscing elit."
1 change: 1 addition & 0 deletions templates/generic/field-types/String/type.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
string
1 change: 1 addition & 0 deletions templates/generic/field-types/Timestamp/sample.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1674053334548000
1 change: 1 addition & 0 deletions templates/generic/field-types/Timestamp/type.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
number
File renamed without changes.
1 change: 1 addition & 0 deletions templates/generic/field-types/Vec/sample.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
1 change: 1 addition & 0 deletions templates/generic/field-types/Vec/type.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Array<{{field_type.type}}>
1 change: 1 addition & 0 deletions templates/generic/field-types/bool/sample.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
false
1 change: 1 addition & 0 deletions templates/generic/field-types/bool/type.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
boolean
File renamed without changes.
1 change: 1 addition & 0 deletions templates/generic/field-types/f32/sample.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.5
1 change: 1 addition & 0 deletions templates/generic/field-types/f32/type.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
number
File renamed without changes.
1 change: 1 addition & 0 deletions templates/generic/field-types/i32/sample.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-10
1 change: 1 addition & 0 deletions templates/generic/field-types/i32/type.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
number
File renamed without changes.
1 change: 1 addition & 0 deletions templates/generic/field-types/u32/sample.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
10
Loading

0 comments on commit baa05a7

Please sign in to comment.