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
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)]
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)]
pub struct Node {
pub registry: String,
}
impl Node {
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)]
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)
}
}
}