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
105
106
107
108
109
110
111
112
113
114
115
116
use crate::{shared, shared::Home};
use anyhow::Result;
use diem_types::account_address::AccountAddress;
use include_dir::{include_dir, Dir};
use std::{
fs,
path::{Path, PathBuf},
};
pub const DEFAULT_BLOCKCHAIN: &str = "goodday";
const EXAMPLES_DIR: Dir = include_dir!("../move/examples");
const MOVE_STDLIB_DIR: Dir = include_dir!("../../diem-move/diem-framework/move-stdlib");
pub fn handle(home: &Home, blockchain: String, pathbuf: PathBuf) -> Result<()> {
let project_path = pathbuf.as_path();
println!("Creating shuffle project in {}", project_path.display());
fs::create_dir_all(project_path)?;
let config = shared::ProjectConfig::new(blockchain);
write_shuffle_project_files(project_path, &config)?;
write_move_project_template(project_path)?;
home.generate_shuffle_path_if_nonexistent()?;
home.write_default_networks_config_into_toml_if_nonexistent()?;
shared::codegen_typescript_libraries(
project_path,
&AccountAddress::from_hex_literal(shared::PLACEHOLDER_ADDRESS)?,
)?;
Ok(())
}
fn write_shuffle_project_files(path: &Path, config: &shared::ProjectConfig) -> Result<()> {
let toml_path = path.join("Shuffle.toml");
let toml_string = toml::to_string(config)?;
fs::write(toml_path, toml_string)?;
Ok(())
}
pub(crate) fn write_move_project_template(project_path: &Path) -> Result<()> {
write_to(EXAMPLES_DIR, project_path)?;
write_to(MOVE_STDLIB_DIR, &project_path.join("stdlib"))?;
Ok(())
}
fn write_to(dir: Dir, path: &Path) -> Result<()> {
for entry in dir.find("**/*").unwrap() {
match entry {
include_dir::DirEntry::Dir(d) => {
fs::create_dir_all(path.join(d.path()))?;
}
include_dir::DirEntry::File(f) => {
let dst = path.join(f.path());
fs::write(dst.as_path(), f.contents())?;
}
}
}
Ok(())
}
#[cfg(test)]
mod test {
use super::*;
use shared::ProjectConfig;
use tempfile::tempdir;
#[test]
fn test_write_project_config() {
let dir = tempdir().unwrap();
let config = ProjectConfig::new(String::from(DEFAULT_BLOCKCHAIN));
write_shuffle_project_files(dir.path(), &config).unwrap();
let config_string =
fs::read_to_string(dir.path().join("Shuffle").with_extension("toml")).unwrap();
let read_config: ProjectConfig = toml::from_str(config_string.as_str()).unwrap();
assert_eq!(config, read_config);
}
#[test]
fn test_handle_e2e() {
let dir = tempdir().unwrap();
let home = Home::new(dir.path()).unwrap();
handle(
&home,
String::from(DEFAULT_BLOCKCHAIN),
PathBuf::from(dir.path()),
)
.unwrap();
let expected_example_content = String::from_utf8_lossy(include_bytes!(
"../../move/examples/main/sources/Message.move"
));
let actual_example_content =
fs::read_to_string(dir.path().join("main/sources/Message.move")).unwrap();
assert_eq!(expected_example_content, actual_example_content);
let expected_example_content = String::from_utf8_lossy(include_bytes!(
"../../../diem-move/diem-framework/move-stdlib/sources/GUID.move"
));
let actual_example_content =
fs::read_to_string(dir.path().join("stdlib/sources/GUID.move")).unwrap();
assert_eq!(expected_example_content, actual_example_content);
}
}