Skip to content

Commit beb6e86

Browse files
committed
feat: v0.1.0
0 parents  commit beb6e86

File tree

10 files changed

+309
-0
lines changed

10 files changed

+309
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/target
2+
Cargo.lock

Cargo.toml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
[package]
2+
name = "hyperlane-cli"
3+
version = "0.1.0"
4+
readme = "README.md"
5+
edition = "2024"
6+
authors = ["root@ltpp.vip"]
7+
license = "MIT"
8+
description = """A command-line tool for Hyperlane framework."""
9+
keywords = ["output", "console", "log", "print", "color"]
10+
repository = "https://github.com/hyperlane-dev/hyperlane-cli"
11+
categories = ["command-line-interface", "development-tools", "visualization"]
12+
exclude = ["target", "Cargo.lock", "sh", ".github"]
13+
14+
[dependencies]
15+
tokio = { version = "1", features = ["process", "rt-multi-thread", "macros"] }
16+
17+
[profile.dev]
18+
incremental = false
19+
opt-level = 3
20+
lto = true
21+
panic = "unwind"
22+
debug = false
23+
codegen-units = 1
24+
strip = "debuginfo"
25+
26+
[profile.release]
27+
incremental = false
28+
opt-level = 3
29+
lto = true
30+
panic = "unwind"
31+
debug = false
32+
codegen-units = 1
33+
strip = "debuginfo"

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2024 尤雨东
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<center>
2+
3+
# hyperlane-cli
4+
5+
[![](https://img.shields.io/crates/v/hyperlane-cli.svg)](https://crates.io/crates/hyperlane-cli)
6+
[![](https://img.shields.io/crates/d/hyperlane-cli.svg)](https://img.shields.io/crates/d/hyperlane-cli.svg)
7+
[![](https://docs.rs/hyperlane-cli/badge.svg)](https://docs.rs/hyperlane-cli)
8+
[![](https://github.com/hyperlane-dev/hyperlane-cli/workflows/Rust/badge.svg)](https://github.com/hyperlane-dev/hyperlane-cli/actions?query=workflow:Rust)
9+
[![](https://img.shields.io/crates/l/hyperlane-cli.svg)](./LICENSE)
10+
11+
</center>
12+
13+
[Official Documentation](https://docs.ltpp.vip/hyperlane-cli/)
14+
15+
[Api Docs](https://docs.rs/hyperlane-cli/latest/)
16+
17+
## Description
18+
19+
> A command-line tool for Hyperlane framework.
20+
21+
## Installation
22+
23+
To install `hyperlane-cli` run cmd:
24+
25+
```shell
26+
cargo add hyperlane-cli
27+
```
28+
29+
## License
30+
31+
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
32+
33+
## Contributing
34+
35+
Contributions are welcome! Please open an issue or submit a pull request.
36+
37+
## Contact
38+
39+
For any inquiries, please reach out to the author at [root@ltpp.vip](mailto:root@ltpp.vip).

src/command/enum.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/// Available commands
2+
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
3+
pub enum CommandType {
4+
/// Format code using cargo fmt
5+
Fmt,
6+
/// Watch files using cargo-watch
7+
Watch,
8+
/// Show help
9+
Help,
10+
/// Show version
11+
Version,
12+
}

src/command/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
mod r#enum;
2+
3+
pub use r#enum::*;

src/config/fn.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
use crate::*;
2+
3+
/// Parse command line arguments
4+
///
5+
/// # Returns
6+
///
7+
/// - `Args`: Parsed arguments
8+
pub fn parse_args() -> Args {
9+
let raw_args: Vec<String> = args().collect();
10+
let mut command: CommandType = CommandType::Help;
11+
let mut check: bool = false;
12+
let mut manifest_path: Option<String> = None;
13+
let mut i: usize = 1;
14+
while i < raw_args.len() {
15+
let arg: &str = raw_args[i].as_str();
16+
match arg {
17+
"-h" | "--help" => {
18+
command = CommandType::Help;
19+
}
20+
"-v" | "--version" => {
21+
command = CommandType::Version;
22+
}
23+
"fmt" => {
24+
if command == CommandType::Help || command == CommandType::Version {
25+
command = CommandType::Fmt;
26+
}
27+
}
28+
"watch" => {
29+
if command == CommandType::Help || command == CommandType::Version {
30+
command = CommandType::Watch;
31+
}
32+
}
33+
"--check" => {
34+
check = true;
35+
}
36+
"--manifest-path" => {
37+
i += 1;
38+
if i < raw_args.len() {
39+
manifest_path = Some(raw_args[i].clone());
40+
}
41+
}
42+
_ => {}
43+
}
44+
i += 1;
45+
}
46+
Args {
47+
command,
48+
check,
49+
manifest_path,
50+
}
51+
}

src/config/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
mod r#fn;
2+
mod r#struct;
3+
4+
pub use {r#fn::*, r#struct::*};

src/config/struct.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
use crate::*;
2+
3+
/// Parsed command line arguments
4+
#[derive(Clone, Debug)]
5+
pub struct Args {
6+
/// The command to execute
7+
pub command: CommandType,
8+
/// Check mode for fmt
9+
pub check: bool,
10+
/// Manifest path for fmt
11+
pub manifest_path: Option<String>,
12+
}

src/main.rs

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
//! Hyperlane CLI
2+
//!
3+
//! A command-line tool for Hyperlane framework.
4+
5+
mod command;
6+
mod config;
7+
8+
use {command::*, config::*};
9+
10+
use std::{
11+
env::args,
12+
process::{ExitStatus, Stdio, exit},
13+
};
14+
15+
use tokio::process::Command;
16+
17+
/// Print help message
18+
fn print_help() {
19+
println!("hyperlane-cli [COMMAND] [OPTIONS]");
20+
println!();
21+
println!("Commands:");
22+
println!(" fmt Format Rust code using cargo fmt");
23+
println!(" watch Watch files and run cargo run using cargo-watch");
24+
println!(" -h, --help Print this help message");
25+
println!(" -v, --version Print version information");
26+
println!();
27+
println!("Fmt Options:");
28+
println!(" --check Check formatting without making changes");
29+
println!(" --manifest-path <PATH> Path to Cargo.toml");
30+
}
31+
32+
/// Print version
33+
fn print_version() {
34+
println!("hyperlane-cli {}", env!("CARGO_PKG_VERSION"));
35+
}
36+
37+
/// Execute fmt command
38+
///
39+
/// # Arguments
40+
/// - `args`: The parsed arguments
41+
///
42+
/// # Returns
43+
/// - `Result<(), std::io::Error>`: Success or error
44+
async fn execute_fmt(args: &Args) -> Result<(), std::io::Error> {
45+
let mut cmd: Command = Command::new("cargo");
46+
cmd.arg("fmt");
47+
if args.check {
48+
cmd.arg("--check");
49+
}
50+
if let Some(ref manifest_path) = args.manifest_path {
51+
cmd.arg("--manifest-path").arg(manifest_path);
52+
}
53+
cmd.stdout(Stdio::inherit()).stderr(Stdio::inherit());
54+
let status: ExitStatus = cmd.status().await?;
55+
if !status.success() {
56+
return Err(std::io::Error::other("cargo fmt failed"));
57+
}
58+
Ok(())
59+
}
60+
61+
/// Check if cargo-watch is installed
62+
///
63+
/// # Returns
64+
/// - `bool`: True if cargo-watch is available
65+
async fn is_cargo_watch_installed() -> bool {
66+
Command::new("cargo-watch")
67+
.arg("--version")
68+
.stdout(Stdio::null())
69+
.stderr(Stdio::null())
70+
.status()
71+
.await
72+
.is_ok_and(|status: ExitStatus| status.success())
73+
}
74+
75+
/// Install cargo-watch using cargo install
76+
///
77+
/// # Returns
78+
/// - `Result<(), std::io::Error>`: Success or error
79+
async fn install_cargo_watch() -> Result<(), std::io::Error> {
80+
println!("cargo-watch not found, installing...");
81+
let mut cmd: Command = Command::new("cargo");
82+
cmd.arg("install").arg("cargo-watch");
83+
cmd.stdout(Stdio::inherit()).stderr(Stdio::inherit());
84+
let status: ExitStatus = cmd.status().await?;
85+
if !status.success() {
86+
return Err(std::io::Error::other("failed to install cargo-watch"));
87+
}
88+
Ok(())
89+
}
90+
91+
/// Execute watch command using cargo-watch
92+
///
93+
/// # Returns
94+
/// - `Result<(), std::io::Error>`: Success or error
95+
async fn execute_watch() -> Result<(), std::io::Error> {
96+
if !is_cargo_watch_installed().await {
97+
install_cargo_watch().await?;
98+
}
99+
let mut cmd: Command = Command::new("cargo-watch");
100+
cmd.arg("--clear")
101+
.arg("--skip-local-deps")
102+
.arg("-q")
103+
.arg("-x")
104+
.arg("run");
105+
cmd.stdout(Stdio::inherit()).stderr(Stdio::inherit());
106+
let status: ExitStatus = cmd.status().await?;
107+
if !status.success() {
108+
return Err(std::io::Error::other("cargo-watch failed"));
109+
}
110+
Ok(())
111+
}
112+
113+
#[tokio::main]
114+
async fn main() {
115+
let args: Args = parse_args();
116+
match args.command {
117+
CommandType::Fmt => {
118+
if let Err(error) = execute_fmt(&args).await {
119+
eprintln!("fmt failed: {error}");
120+
exit(1);
121+
}
122+
}
123+
CommandType::Watch => {
124+
if let Err(error) = execute_watch().await {
125+
eprintln!("watch failed: {error}");
126+
exit(1);
127+
}
128+
}
129+
CommandType::Help => print_help(),
130+
CommandType::Version => print_version(),
131+
}
132+
}

0 commit comments

Comments
 (0)