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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
use crate::Result;
use etc::{Etc, FileSystem, Meta, Read, Write};
use serde::{Deserialize, Serialize};
use std::process::Command;
fn get(src: &str, key: &str) -> String {
if let Some(mut begin) = src.find(key) {
begin = src[begin..].find('=').unwrap_or(0) + begin + 1;
let end = src[begin..].find('\n').unwrap_or(0) + begin;
src[begin..end].trim().to_string()
} else {
String::new()
}
}
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct MetaData {
pub authors: Vec<String>,
pub version: String,
pub license: String,
}
impl MetaData {
pub fn tuple(&self) -> Vec<(&str, String, Option<&str>)> {
vec![
(
"authors =",
format!("authors = {:?}", self.authors),
Some("]\n"),
),
("license =", format!("license = \"{}\"", self.license), None),
]
}
}
impl Default for MetaData {
fn default() -> MetaData {
let git_config = Command::new("git")
.args(vec!["config", "--global", "--list"])
.output()
.expect("Failed to execute git command")
.stdout;
let git_config_str = String::from_utf8_lossy(&git_config);
let author = get(&git_config_str, "user.name");
let mail = get(&git_config_str, "user.email");
MetaData {
authors: vec![format!("{} <{}>", author, mail)],
version: "0.1.0".to_string(),
license: "MIT".to_string(),
}
}
}
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct Node {
pub registry: String,
}
impl Node {
pub fn name_space(&self) -> String {
let name = self.name();
let end = self.registry.find(&name).unwrap_or(0);
let begin = (&self.registry[..end - 1]).rfind('/').unwrap_or(0) + 1;
self.registry[begin..end].to_string()
}
pub fn name(&self) -> String {
let begin = self.registry.rfind('/').unwrap_or(0) + 1;
let end = self.registry.rfind(".git").unwrap_or(0);
if begin - 1 == end {
"substrate"
} else {
&self.registry[begin..end]
}
.to_string()
}
}
impl Default for Node {
fn default() -> Node {
Node {
registry: "https://github.com/paritytech/substrate.git".to_string(),
}
}
}
#[derive(Default, Deserialize, Serialize, Debug, Clone)]
pub struct Config {
pub metadata: MetaData,
pub node: Node,
}
impl Config {
pub fn gen_default(config: &Etc) -> Result<Config> {
let default = Config::default();
config.write(toml::to_string(&default)?)?;
Ok(default)
}
pub fn new() -> Result<Config> {
let mut home = dirs::home_dir().expect("Could not find home dir");
home.push(".sup");
let etc = Etc::from(&home);
let config = etc.open("config.toml")?;
if config.real_path()?.exists() {
let bytes = config.read()?;
if let Ok(cur) = toml::from_slice::<Config>(&bytes) {
Ok(cur)
} else {
Self::gen_default(&config)
}
} else {
Self::gen_default(&config)
}
}
}