-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathautodoc.rs
executable file
Β·169 lines (152 loc) Β· 5.11 KB
/
autodoc.rs
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#!/usr/bin/env cargo +nightly -Zscript
// Returns current version of the package
// reads the Cargo.toml file and returns the version and line number
fn get_pkg_version() -> (String, usize) {
let cargo_toml = std::fs::read_to_string("Cargo.toml").unwrap();
let mut line_number = 0;
for line in cargo_toml.lines() {
line_number += 1;
if line.starts_with("version") {
let version = line
.split("=")
.nth(1)
.expect("Invariant state")
.trim()
.trim_matches('"')
.to_string();
return (version, line_number);
}
}
return ("".to_string(), 0);
}
fn get_next_version(current_version: &str, segment_or_version: Option<&str>) -> String {
let mut version = current_version
.split(".")
.map(|s| s.parse::<u32>().unwrap())
.collect::<Vec<u32>>();
match segment_or_version.unwrap_or("patch") {
"major" => {
version[0] += 1;
version[1] = 0;
version[2] = 0;
}
"minor" => {
version[1] += 1;
version[2] = 0;
}
"patch" => version[2] += 1,
_ => return segment_or_version.expect("Invariant state").to_string(),
}
version
.iter()
.map(|v| v.to_string())
.collect::<Vec<String>>()
.join(".")
}
fn write_pkg_version(new_version: &str, line_number: usize) {
let cargo_toml = std::fs::read_to_string("Cargo.toml").unwrap();
let mut curr_line_number = 0;
let new_cargo_toml = cargo_toml
.lines()
.map(|line| {
curr_line_number += 1;
if curr_line_number == line_number {
format!("version = \"{new_version}\"")
} else {
line.to_string()
}
})
.collect::<Vec<String>>()
.join("\n");
// Add final newline
let new_cargo_toml = format!("{}\n", new_cargo_toml);
// Write new Cargo.toml
std::fs::write("Cargo.toml", new_cargo_toml).unwrap();
}
// Updates the README.md file matches the line prefix
// and replaces the contents from next line to the line containing "```"
// with the output of the Command passed
fn update_readme(line_prefix: &str, command: &mut std::process::Command) {
let readme = std::fs::read_to_string("README.md").unwrap();
let mut new_readme = Vec::new();
let output = command.output().expect("Failed to execute command");
// Trim output to remove trailing space on each line
let output_lines = output
.stdout
.iter()
.map(|b| *b as char)
.collect::<String>()
.split("\n")
.map(|s| s.to_string().trim_end().to_string())
.collect::<Vec<String>>()
.join("\n");
// Consume iterator until line_prefix is found
// Then merge output lines and skip iterator until "```" is found
// append the output lines to the new_readme vector
let mut lines = readme.lines();
while let Some(line) = lines.next() {
if line.starts_with(line_prefix) {
new_readme.push(line.to_string());
new_readme.push(output_lines.clone());
while let Some(line) = lines.next() {
if line.starts_with("```") {
new_readme.push(line.to_string());
break;
}
}
} else {
new_readme.push(line.to_string());
}
}
// Add final newline
new_readme.push("".to_string());
// Write new README.md
std::fs::write("README.md", new_readme.join("\n")).unwrap();
}
fn main() {
let (current_version, line_number) = get_pkg_version();
let mut args = std::env::args();
let should_commit = args.any(|arg| arg == "--commit");
// Skip first argument which is the script name
// skip any flags that start with `--`
let arg = args.skip(1).skip_while(|arg| arg.starts_with("--")).next();
let segment_or_version = arg.as_deref();
// Bump version
let new_version = get_next_version(¤t_version, segment_or_version);
println!("Bumping version from {current_version} to {new_version}");
// Update Cargo.toml at line number
write_pkg_version(&new_version, line_number);
// Invoke cargo to build the package
println!("Building package");
std::process::Command::new("cargo")
.arg("build")
.output()
.expect("Failed to build package");
// Update README.md
println!("Updating README.md");
update_readme(
"$ toggl help",
std::process::Command::new("cargo")
.arg("run")
.arg("--")
.arg("help"),
);
update_readme(
"$ toggl help start",
std::process::Command::new("cargo")
.arg("run")
.arg("--")
.arg("help")
.arg("start"),
);
if !should_commit {
return;
}
println!("Committing changes");
std::process::Command::new("git")
.arg("commit")
.arg("-am")
.arg(format!("π’ Release {}", new_version))
.output()
.expect("Failed to commit changes");
}