-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathcli.rs
More file actions
104 lines (94 loc) · 4.09 KB
/
cli.rs
File metadata and controls
104 lines (94 loc) · 4.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#![doc = include_str!("../guides/cli.md")]
use crate::error::ScaffoldError;
use crate::file_tree::load_directory_into_memory;
use crate::scaffold::config::ScaffoldConfig;
use crate::scaffold::example::ExampleType;
use crate::scaffold::web_app::template_type::TemplateType;
use colored::Colorize;
use std::{path::Path, str::FromStr};
use structopt::StructOpt;
mod collection;
mod dna;
mod entry_type;
mod example;
mod link_type;
mod template;
mod web_app;
mod zome;
#[derive(Debug, StructOpt)]
pub struct HcScaffold {
#[structopt(short, long, parse(try_from_str = TemplateType::from_str))]
/// The template to use for the hc-scaffold commands
/// Can either be an option from the built-in templates: "vanilla", "vue", "lit", "svelte", "react", "headless"
/// Or a path to a custom template
template: Option<TemplateType>,
#[structopt(subcommand)]
command: HcScaffoldCommand,
}
/// A command-line interface for creating and modifying a Holochain application (hApp).
#[derive(Debug, StructOpt)]
#[structopt(setting = structopt::clap::AppSettings::InferSubcommands)]
pub enum HcScaffoldCommand {
WebApp(web_app::WebApp),
Template(template::Template),
Dna(dna::Dna),
Zome(zome::Zome),
EntryType(entry_type::EntryType),
LinkType(link_type::LinkType),
Collection(collection::Collection),
Example(example::Example),
}
impl HcScaffold {
pub async fn run(self) -> anyhow::Result<()> {
let current_dir = std::env::current_dir()?;
let scaffold_config = ScaffoldConfig::from_package_json_path(¤t_dir)?;
let template_type = self.get_template_type(¤t_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,
}
}
fn get_template_type(
&self,
current_dir: &Path,
scaffold_config: Option<&ScaffoldConfig>,
) -> Result<TemplateType, ScaffoldError> {
// Read template_type config if no `--template` flag is provided and use it or
// ensure that if a `--template` is explicitly provided, it matches the original
// template the app was scaffolded with
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.name().italic(),
config.template.name().italic(),
)));
}
(Some(config), _) => Some(&config.template),
(_, t) => t.as_ref(),
};
match template {
Some(template) => Ok(template.clone()),
None => {
let template_type = match &self.command {
HcScaffoldCommand::WebApp { .. } => TemplateType::choose()?,
HcScaffoldCommand::Example(example::Example { ref example, .. }) => {
match example {
Some(ExampleType::HelloWorld) => TemplateType::Vanilla,
Some(ExampleType::Forum) => TemplateType::choose_non_vanilla()?,
None => TemplateType::choose_non_headless()?,
}
}
_ => TemplateType::try_from(&load_directory_into_memory(current_dir)?)?,
};
Ok(template_type)
}
}
}
}