Skip to content

Commit bb23b64

Browse files
committed
Merge branch 'feature/flow' into develop
2 parents 291c48b + 65b4289 commit bb23b64

File tree

9 files changed

+218
-17
lines changed

9 files changed

+218
-17
lines changed

Cargo.lock

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "wutong"
3-
version = "0.1.0"
3+
version = "0.2.0"
44
edition = "2021"
55
authors = ["Gavin Zheng<gav.zheng@outlook.com"]
66
description = "A Swiss Army Knife for Developers.🌳"
@@ -12,6 +12,6 @@ license = "MIT"
1212
readme = "README.md"
1313

1414
[dependencies]
15-
clap = "4.5.26"
15+
clap = "4.5.34"
1616
colored = "3.0.0"
1717
md5 = "0.7.0"

README.md

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ In our daily project development, we frequently encounter situations where we ne
2424
---
2525

2626
## How to Install Wutong
27-
If you are a MacOS user, you can use:
27+
If you are a macOS user, you can use:
2828
```bash
29+
brew tap GavZheng/wutong
2930
brew install wutong
3031
```
3132
If you are a Windows or Linux user, please wait for the subsequent version.
@@ -35,7 +36,7 @@ P.S.: Of course, you can compile Wutong yourself.
3536

3637
## How to Use Wutong
3738
You can obtain detailed information by typing `wutong --help` in the command line.
38-
The general functions of Wutong are listed below (v0.1.0-beta):
39+
The general functions of Wutong are listed below (v0.2.0):
3940

4041
| Function | Description |
4142
|----------|--------------------------------------------------------------|
@@ -44,6 +45,7 @@ The general functions of Wutong are listed below (v0.1.0-beta):
4445
| color | Convert between RGB and Hex colors |
4546
| md5 | Hash input strings using MD5 |
4647
| charcode | Convert string encodings |
48+
| flow | Manage git repositories according to the Gitflow workflow |
4749

4850
---
4951

@@ -71,5 +73,21 @@ We sincerely thank the following individuals who have made outstanding contribut
7173

7274
---
7375

76+
FAQ
77+
78+
Q1: Why is it named "Wutong"?
79+
A: The name originates from developer Gavin's friend, Silent, whose favorite tree species is the Chinese parasol tree (梧桐). "Wutong" is the Pinyin transliteration of the tree's Chinese name.
80+
81+
Q2: Why was Rust chosen as the development language?
82+
A: Rust was selected as the optimal technical choice after evaluating languages like Python, C++, and C, due to its cross-platform capabilities, memory safety features, and high-performance execution that align with the project's requirements.
83+
84+
Q3: Why is only macOS currently supported?
85+
A: Current development prioritizes core feature refinement and rapid iteration. Windows and Linux versions are on the roadmap, with multi-platform adaptation scheduled to commence once core functionalities are stabilized.
86+
87+
Q4: Where can I learn more about Gavin?
88+
A: Visit [Gavin's GitHub profile](https://github.com/GavZheng) to explore his technical contributions and open-source projects.
89+
90+
---
91+
7492
## License
7593
[MIT](./LICENSE) © 2025 Gavin Zheng

docs/zh/README_zh.md

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,18 @@
3232
---
3333

3434
## 如何安装梧桐
35-
> [!NOTE]
36-
> 梧桐在测试阶段不提供安装方式,如希望体验请自行编译。在正式版发布后,梧桐将会提供安装方式。
37-
35+
如果您是 macOS 用户,则可以使用:
36+
```bash
37+
brew tap GavZheng/wutong
38+
brew install wutong
39+
```
40+
如果您是 Windows 或 Linux 用户,请等待后续版本。
41+
P.S.:当然可以自己编译梧桐。
3842
---
3943

4044
## 如何使用梧桐
4145
你可以通过在命令行键入`wutong --help`来获取详细信息。
42-
梧桐的大致功能如下表(v0.1.0-alpha
46+
梧桐的大致功能如下表(v0.2.0
4347

4448
| 功能 | 描述 |
4549
|----------|----------------------------|
@@ -48,6 +52,7 @@
4852
| color | RGB和Hex颜色的相互转换 |
4953
| md5 | 将输入的字符串进行md5哈希 |
5054
| charcode | 字符串编码转换 |
55+
| flow | 根据 Gitflow 工作流程管理 git 存储库 |
5156

5257
---
5358

@@ -73,5 +78,20 @@
7378

7479
---
7580

81+
## FAQ
82+
Q1: 为什么叫梧桐?
83+
A:这个名字来自我(Gavin)的一个朋友(Silent),梧桐是她最喜欢的树。“Wutong”是梧桐的拼音。
84+
85+
Q2: 为何选择Rust作为开发语言?
86+
A: Rust凭借其卓越的跨平台能力、内存安全特性和高效执行性能,在综合评估Python/C++/C等候选语言后,被确认为满足项目需求的最佳技术选型。
87+
88+
Q3: 当前为何仅支持macOS平台?
89+
A: 现阶段开发重心聚焦于核心功能完善与快速迭代。Windows/Linux版本已列入roadmap,将在主体功能稳定后启动多平台适配工作。
90+
91+
Q4:更多关于Gavin?
92+
A:你可以访问[Gavin的Github主页](https://github.com/GavZheng)
93+
94+
---
95+
7696
## 许可证
7797
[MIT](../../LICENSE) © 2025 Gavin Zheng

src/flow/branch.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
use crate::BranchType;
2+
use std::process;
3+
4+
pub fn branch(branch_type: BranchType, branch_name: &str) -> Result<(), String> {
5+
let git_path = crate::flow::git::which_git().map_err(|e| e.to_string())?;
6+
7+
let prefix = match branch_type {
8+
BranchType::Feature => "feature",
9+
BranchType::Release => "release",
10+
BranchType::Hotfix => "hotfix",
11+
};
12+
13+
let branch = format!("{}/{}", prefix, branch_name);
14+
15+
let output = process::Command::new(&git_path)
16+
.arg("checkout")
17+
.arg("-b")
18+
.arg(&branch)
19+
.output()
20+
.map_err(|e| format!("Failed to execute Git command: {}", e))?;
21+
22+
if !output.status.success() {
23+
let error_msg = String::from_utf8_lossy(&output.stderr);
24+
return Err(format!(
25+
"Failed to create branch '{}': {}",
26+
branch, error_msg
27+
));
28+
}
29+
30+
Ok(())
31+
}

src/flow/git.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
use std::env::consts::OS;
2+
use std::process;
3+
4+
pub fn which_git() -> Result<String, String> {
5+
let (cmd, arg) = if OS == "windows" {
6+
("where", "git")
7+
} else {
8+
("which", "git")
9+
};
10+
11+
let output = process::Command::new(cmd)
12+
.arg(arg)
13+
.output()
14+
.map_err(|e| format!("Command execution failed:{}", e))?;
15+
16+
if !output.status.success() {
17+
return Err("The Git executable could not be found".to_string());
18+
}
19+
20+
let path_str = String::from_utf8_lossy(&output.stdout)
21+
.trim()
22+
.lines()
23+
.next()
24+
.ok_or("No valid path found")?
25+
.to_string();
26+
27+
if path_str.is_empty() || !std::path::Path::new(&path_str).exists() {
28+
return Err("The found Git path is invalid".to_string());
29+
}
30+
31+
Ok(path_str)
32+
}

src/flow/merge.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
use std::process;
2+
3+
pub fn merge(branch_name: &str) -> Result<(), String> {
4+
let git_path = crate::flow::git::which_git().map_err(|e| e.to_string())?;
5+
6+
let output = process::Command::new(&git_path)
7+
.arg("merge")
8+
.arg("--no-ff")
9+
.arg(branch_name)
10+
.output()
11+
.map_err(|e| format!("Failed to execute Git command: {}", e))?;
12+
13+
if !output.status.success() {
14+
let error_msg = String::from_utf8_lossy(&output.stderr);
15+
return Err(format!(
16+
"Failed to merge branch '{}': {}",
17+
branch_name, error_msg
18+
));
19+
}
20+
21+
Ok(())
22+
}

src/flow/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pub mod branch;
2+
pub mod git;
3+
pub mod merge;

src/main.rs

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,22 @@ mod base;
22
mod base_conversion;
33
mod charcode;
44
mod color;
5+
mod flow;
56
mod md5;
67

78
use clap::{Arg, ArgGroup, Command};
8-
use colored::*;
9+
use colored::Colorize;
10+
11+
#[derive(Debug, Clone, Copy)]
12+
pub enum BranchType {
13+
Feature,
14+
Release,
15+
Hotfix,
16+
}
917

1018
fn main() {
1119
let matches = Command::new("Wutong")
12-
.version("0.1.0")
20+
.version("0.2.0")
1321
.about("Wutong - A Swiss Army Knife of Developers.🌳")
1422
.author("Gavin Zheng<gav.zheng@outlook.com>")
1523
.subcommand(
@@ -82,6 +90,40 @@ fn main() {
8290
.index(1),
8391
),
8492
)
93+
.subcommand(
94+
Command::new("flow")
95+
.about("Create and merge branches and release versions according to GitFlow.")
96+
.arg(
97+
Arg::new("feature")
98+
.short('f')
99+
.long("feature")
100+
.help("Create a new feature branch."),
101+
)
102+
.arg(
103+
Arg::new("release")
104+
.short('r')
105+
.long("release")
106+
.help("Create a new release branch."),
107+
)
108+
.arg(
109+
Arg::new("hotfix")
110+
.short('H')
111+
.long("hotfix")
112+
.help("Create a new hotfix branch."),
113+
)
114+
.arg(
115+
Arg::new("merge")
116+
.short('m')
117+
.long("merge")
118+
.help("Merge branches."),
119+
)
120+
.group(
121+
ArgGroup::new("branch_type_option")
122+
.args(["feature", "release", "hotfix", "merge"])
123+
.required(true)
124+
.multiple(false),
125+
),
126+
)
85127
.get_matches();
86128

87129
match matches.subcommand() {
@@ -214,6 +256,39 @@ fn main() {
214256
Err(error) => println!("{} {}", "Error:".red(), error),
215257
}
216258
}
259+
Some(("flow", subcommand_flow)) => {
260+
let subcommands = [
261+
("feature", BranchType::Feature),
262+
("release", BranchType::Release),
263+
("hotfix", BranchType::Hotfix),
264+
];
265+
266+
if let Some((sub_cmd, branch_type)) = subcommands
267+
.iter()
268+
.find(|(name, _)| subcommand_flow.contains_id(name))
269+
.copied()
270+
{
271+
let arg = subcommand_flow.get_one::<String>(sub_cmd).unwrap();
272+
match flow::branch::branch(branch_type, arg) {
273+
Ok(_) => println!("Done."),
274+
Err(e) => {
275+
eprintln!("{} {}", "Error:".red(), e);
276+
std::process::exit(1);
277+
}
278+
}
279+
}
280+
281+
if subcommand_flow.contains_id("merge") {
282+
let arg = subcommand_flow.get_one::<String>("merge").unwrap();
283+
match flow::merge::merge(arg) {
284+
Ok(_) => println!("Done."),
285+
Err(e) => {
286+
eprintln!("{} {}", "Error:".red(), e);
287+
std::process::exit(1);
288+
}
289+
}
290+
}
291+
}
217292
_ => {}
218293
}
219294
}

0 commit comments

Comments
 (0)