Skip to content

Commit 0352015

Browse files
committed
Add dedicated dev tool
1 parent 5d37017 commit 0352015

21 files changed

+1360
-0
lines changed

vdev/Cargo.lock

+685
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vdev/Cargo.toml

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
[package]
2+
name = "vdev"
3+
version = "0.1.0"
4+
edition = "2021"
5+
authors = ["Vector Contributors <[email protected]>"]
6+
license = "MPL-2.0"
7+
readme = "README.md"
8+
publish = false
9+
10+
[dependencies]
11+
cached = "0.40.0"
12+
clap = { version = "4.0.18", features = ["derive"] }
13+
clap-verbosity-flag = "2.0.0"
14+
confy = "0.5.1"
15+
# remove this when stabilized https://doc.rust-lang.org/stable/std/path/fn.absolute.html
16+
dunce = "1.0.3"
17+
env_logger = "0.9.1"
18+
home = "0.5.4"
19+
log = "0.4.17"
20+
os_info = { version = "3.5.1", default-features = false }
21+
# watch https://github.com/epage/anstyle for official interop with Clap
22+
owo-colors = { version = "3.5.0", features = ["supports-colors"] }
23+
serde = { version = "1.0", features = ["derive"] }
24+
25+
# https://github.com/rust-lang/cargo/issues/6745#issuecomment-472667516
26+
[workspace]

vdev/README.md

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# vdev
2+
3+
-----
4+
5+
This is the command line tooling for Vector development.
6+
7+
**Table of Contents**
8+
9+
- [Installation](#installation)
10+
- [Configuration](#configuration)
11+
- [Repository](#repository)
12+
- [Starship](#starship)
13+
14+
## Installation
15+
16+
```text
17+
cargo install -f --path vdev
18+
```
19+
20+
## Configuration
21+
22+
### Repository
23+
24+
Setting the path to the repository explicitly allows the application to be used at any time no matter the current working directory.
25+
26+
```text
27+
vdev config set repo .
28+
```
29+
30+
To test, enter your home directory and then run:
31+
32+
```text
33+
vdev exec ls
34+
```
35+
36+
### Starship
37+
38+
A custom command for the [Starship](https://starship.rs) prompt is available.
39+
40+
```toml
41+
format = """
42+
...
43+
${custom.vdev}\
44+
...
45+
$line_break\
46+
...
47+
$character"""
48+
49+
# <clipped>
50+
51+
[custom.vdev]
52+
command = "vdev meta starship"
53+
when = true
54+
# Windows
55+
# shell = ["cmd", "/C"]
56+
# Other
57+
# shell = ["sh", "--norc"]
58+
```

vdev/src/app.rs

+140
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
use log::{Level, LevelFilter};
2+
use owo_colors::{
3+
OwoColorize,
4+
Stream::{Stderr, Stdout},
5+
};
6+
use std::env;
7+
use std::process::Command;
8+
9+
use crate::config::{Config, ConfigFile};
10+
use crate::platform::Platform;
11+
12+
pub struct Application {
13+
pub(crate) path: String,
14+
pub(crate) config_file: ConfigFile,
15+
pub(crate) config: Config,
16+
pub(crate) platform: Platform,
17+
verbosity: LevelFilter,
18+
}
19+
20+
impl Application {
21+
pub fn new(verbosity: LevelFilter) -> Application {
22+
let platform = Platform::new();
23+
let config_file = ConfigFile::new();
24+
let config_model = config_file.load();
25+
26+
// Set the path to the repository for the entire application
27+
let path = if !config_model.repo.is_empty() {
28+
config_model.repo.to_string()
29+
} else {
30+
match env::current_dir() {
31+
Ok(p) => p.display().to_string(),
32+
Err(_) => ".".to_string(),
33+
}
34+
};
35+
36+
Application {
37+
path: path.to_string(),
38+
config_file: config_file,
39+
config: config_model,
40+
platform: platform,
41+
verbosity: verbosity,
42+
}
43+
}
44+
45+
pub fn exit(&self, code: i32) {
46+
std::process::exit(code);
47+
}
48+
49+
pub fn abort<T: AsRef<str>>(&self, text: T) {
50+
self.display_error(text);
51+
self.exit(1);
52+
}
53+
54+
pub fn command<T: AsRef<str>>(&self, program: T) -> Command {
55+
let mut cmd = Command::new(program.as_ref());
56+
cmd.current_dir(self.path.clone());
57+
cmd
58+
}
59+
60+
pub fn display<T: AsRef<str>>(&self, text: T) {
61+
// Simply bold rather than bright white for terminals with white backgrounds
62+
println!(
63+
"{}",
64+
text.as_ref().if_supports_color(Stdout, |text| text.bold())
65+
);
66+
}
67+
68+
#[allow(dead_code)]
69+
pub fn display_trace<T: AsRef<str>>(&self, text: T) {
70+
if Level::Trace <= self.verbosity {
71+
eprintln!(
72+
"{}",
73+
text.as_ref().if_supports_color(Stderr, |text| text.bold())
74+
);
75+
}
76+
}
77+
78+
#[allow(dead_code)]
79+
pub fn display_debug<T: AsRef<str>>(&self, text: T) {
80+
if Level::Debug <= self.verbosity {
81+
eprintln!(
82+
"{}",
83+
text.as_ref().if_supports_color(Stderr, |text| text.bold())
84+
);
85+
}
86+
}
87+
88+
#[allow(dead_code)]
89+
pub fn display_info<T: AsRef<str>>(&self, text: T) {
90+
if Level::Info <= self.verbosity {
91+
eprintln!(
92+
"{}",
93+
text.as_ref().if_supports_color(Stderr, |text| text.bold())
94+
);
95+
}
96+
}
97+
98+
#[allow(dead_code)]
99+
pub fn display_success<T: AsRef<str>>(&self, text: T) {
100+
if Level::Info <= self.verbosity {
101+
eprintln!(
102+
"{}",
103+
text.as_ref()
104+
.if_supports_color(Stderr, |text| text.bright_cyan())
105+
);
106+
}
107+
}
108+
109+
#[allow(dead_code)]
110+
pub fn display_waiting<T: AsRef<str>>(&self, text: T) {
111+
if Level::Info <= self.verbosity {
112+
eprintln!(
113+
"{}",
114+
text.as_ref()
115+
.if_supports_color(Stderr, |text| text.bright_magenta())
116+
);
117+
}
118+
}
119+
120+
#[allow(dead_code)]
121+
pub fn display_warning<T: AsRef<str>>(&self, text: T) {
122+
if Level::Warn <= self.verbosity {
123+
eprintln!(
124+
"{}",
125+
text.as_ref()
126+
.if_supports_color(Stderr, |text| text.bright_yellow())
127+
);
128+
}
129+
}
130+
131+
pub fn display_error<T: AsRef<str>>(&self, text: T) {
132+
if Level::Error <= self.verbosity {
133+
eprintln!(
134+
"{}",
135+
text.as_ref()
136+
.if_supports_color(Stderr, |text| text.bright_red())
137+
);
138+
}
139+
}
140+
}

vdev/src/commands/build.rs

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
use clap::Args;
2+
3+
use crate::app::Application;
4+
5+
/// Build Vector
6+
#[derive(Args, Debug)]
7+
#[command()]
8+
pub struct Cli {
9+
/// The build target e.g. x86_64-unknown-linux-musl
10+
target: Option<String>,
11+
12+
/// Build with optimizations
13+
#[arg(short, long)]
14+
release: bool,
15+
16+
/// The feature to activate (multiple allowed)
17+
#[arg(short = 'F', long)]
18+
feature: Vec<String>,
19+
}
20+
21+
impl Cli {
22+
pub fn exec(&self, app: &Application) {
23+
let mut command = app.command("cargo");
24+
command.args(["build", "--no-default-features"]);
25+
26+
if self.release {
27+
command.arg("--release");
28+
}
29+
30+
command.arg("--features");
31+
if !self.feature.is_empty() {
32+
command.args([self.feature.join(",")]);
33+
} else {
34+
if app.platform.windows() {
35+
command.arg("default-msvc");
36+
} else {
37+
command.arg("default");
38+
}
39+
};
40+
41+
if let Some(target) = self.target.as_deref() {
42+
command.args(["--target", target]);
43+
} else {
44+
command.args(["--target", &app.platform.default_target()]);
45+
};
46+
47+
let status = command.status().expect("failed to execute cargo");
48+
if !status.success() {
49+
app.abort(format!("failed with exit code: {status}"));
50+
}
51+
}
52+
}

vdev/src/commands/cli.rs

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
use clap::{Parser, Subcommand};
2+
use clap_verbosity_flag::{InfoLevel, Verbosity};
3+
4+
use crate::app::Application;
5+
use crate::commands;
6+
7+
/// Vector's unified dev tool
8+
#[derive(Parser, Debug)]
9+
#[
10+
command(
11+
bin_name = "vdev",
12+
author,
13+
version,
14+
about,
15+
disable_help_subcommand = true,
16+
long_about = None,
17+
)
18+
]
19+
pub struct Cli {
20+
#[clap(flatten)]
21+
pub(crate) verbose: Verbosity<InfoLevel>,
22+
23+
#[command(subcommand)]
24+
command: Commands,
25+
}
26+
27+
#[derive(Subcommand, Debug)]
28+
enum Commands {
29+
/// Build Vector
30+
Build(commands::build::Cli),
31+
/// Manage the config file
32+
Config(commands::config::cli::Cli),
33+
/// Execute a command within the repository
34+
Exec(commands::exec::Cli),
35+
/// Collection of useful utilities
36+
Meta(commands::meta::cli::Cli),
37+
}
38+
39+
impl Cli {
40+
pub fn exec(&self, app: &Application) {
41+
match &self.command {
42+
Commands::Build(cli) => cli.exec(&app),
43+
Commands::Config(cli) => cli.exec(&app),
44+
Commands::Exec(cli) => cli.exec(&app),
45+
Commands::Meta(cli) => cli.exec(&app),
46+
}
47+
}
48+
}

vdev/src/commands/config/cli.rs

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
use clap::{Args, Subcommand};
2+
3+
use crate::app::Application;
4+
use crate::commands;
5+
6+
/// Manage the config file
7+
#[derive(Args, Debug)]
8+
#[command()]
9+
pub struct Cli {
10+
#[command(subcommand)]
11+
command: Commands,
12+
}
13+
14+
#[derive(Subcommand, Debug)]
15+
enum Commands {
16+
/// Locate the config file
17+
Find(commands::config::find::Cli),
18+
/// Modify the config file
19+
Set(commands::config::set::cli::Cli),
20+
}
21+
22+
impl Cli {
23+
pub fn exec(&self, app: &Application) {
24+
match &self.command {
25+
Commands::Find(cli) => cli.exec(&app),
26+
Commands::Set(cli) => cli.exec(&app),
27+
}
28+
}
29+
}

vdev/src/commands/config/find.rs

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
use clap::Args;
2+
3+
use crate::app::Application;
4+
5+
/// Locate the config file
6+
#[derive(Args, Debug)]
7+
#[command()]
8+
pub struct Cli {}
9+
10+
impl Cli {
11+
pub fn exec(&self, app: &Application) {
12+
app.display(format!("{}", app.config_file.path().display()));
13+
}
14+
}

vdev/src/commands/config/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pub mod cli;
2+
pub mod find;
3+
pub mod set;

0 commit comments

Comments
 (0)