Compare commits

...

3 Commits

5 changed files with 93 additions and 21 deletions

1
Cargo.lock generated
View File

@ -196,6 +196,7 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
name = "vnetod"
version = "0.3.3"
dependencies = [
"atty",
"clap",
"termcolor",
]

View File

@ -13,7 +13,8 @@ categories = ["command-line-interface", "config", "development-tools"]
[dependencies]
clap = { version = "3.2.15", default-features = false, features = ["std", "env", "derive"] }
atty = { version = "0.2.14", optional = true }
termcolor = { version = "1.1.3", optional = true }
[features]
color = ["clap/color", "dep:termcolor"]
color = ["clap/color", "dep:atty", "dep:termcolor"]

View File

@ -48,20 +48,19 @@
config = {
Volumes."/data" = { };
WorkingDir = "/data";
Entrypoint = [ "${vnetod}/bin/vnetod" ];
Entrypoint = [ "${coloredVnetod}/bin/vnetod" ];
};
};
mkApp = prog: {
type = "app";
program = "${vnetod}/bin/vnetod";
};
in
{
apps = {
default = {
type = "app";
program = "${vnetod}/bin/vnetod";
};
colored = {
type = "app";
program = "${coloredVnetod}/bin/vnetod";
};
default = mkApp vnetod;
colored = mkApp coloredVnetod;
};
packages = {

View File

@ -20,7 +20,7 @@ use std::path::PathBuf;
use clap::Parser;
#[derive(Parser)]
#[derive(Parser, Debug)]
#[clap(
author,
version,
@ -62,4 +62,63 @@ pub struct Args {
help = "Environment varible sections that will be enabled"
)]
pub sections: Vec<String>,
#[cfg(feature = "color")]
#[clap(
long,
value_enum,
default_value = "auto",
long_help = "
This flag controls when to use colors. The default setting is 'auto', which
means vnetod will try to guess when to use colors. For example, if vnetod is
printing to a terminal, then it will use colors, but if it is redirected to a
file or a pipe, then it will suppress color output. vnetod will suppress color
output in some other circumstances as well. For example, if the TERM
environment variable is not set or set to 'dumb', then vnetod will not use
colors.
The possible values for this flag are:
never Colors will never be used.
auto The default. vnetod tries to be smart.
always Colors will always be used regardless of where output is sent.
ansi Like 'always', but emits ANSI escapes (even in a Windows console).
"
)]
pub color: ColorVariant,
}
#[cfg(feature = "color")]
#[derive(clap::ValueEnum, Clone, Debug)]
pub enum ColorVariant {
Auto,
Always,
Ansi,
Never,
}
#[cfg(feature = "color")]
impl From<ColorVariant> for termcolor::ColorChoice {
fn from(col: ColorVariant) -> Self {
match col {
ColorVariant::Never => Self::Never,
ColorVariant::Always => Self::Always,
ColorVariant::Ansi => Self::AlwaysAnsi,
ColorVariant::Auto => {
if atty::is(atty::Stream::Stdout) {
// Otherwise let's `termcolor` decide by inspecting the environment. From the [doc]:
// - If `NO_COLOR` is set to any value, then colors will be suppressed.
// - If `TERM` is set to dumb, then colors will be suppressed.
// - In non-Windows environments, if `TERM` is not set, then colors will be suppressed.
//
// [doc]: https://github.com/BurntSushi/termcolor#automatic-color-selection
Self::Auto
} else {
// Colors should be deactivated if the terminal is not a tty.
Self::Never
}
}
}
}
}

View File

@ -15,7 +15,7 @@
//!
#[cfg(feature = "color")]
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
use termcolor::{Color, ColorSpec, StandardStream, WriteColor};
use crate::{cli::Args, domain};
use std::fs::File;
@ -41,17 +41,34 @@ impl std::error::Error for Error {}
pub fn execute(args: &Args) -> Result<(), Error> {
let content = std::fs::read_to_string(&args.file).map_err(|_| Error::OpenFile)?;
if args.dry_run {
println!("Your file will be changed to the following")
}
let fs_writer = (!args.dry_run)
.then(|| {
File::create(args.output.as_ref().unwrap_or(&args.file)).map_err(|_| Error::OpenFile)
})
.transpose()?;
#[cfg(feature = "color")]
let color = args.color.clone();
println!();
let new_content = domain::switch::execute(domain::switch::Request {
content: &content,
content: &content.trim(),
sections: &args.sections,
on_line: Some(Box::new(print_line)),
on_line: Some(Box::new(move |line| {
#[cfg(feature = "color")]
print_line(line, color.clone());
#[cfg(not(feature = "color"))]
print!("{}", line)
})),
});
println!();
if let Some(mut fs_writer) = fs_writer {
fs_writer
.write_all(new_content.as_bytes())
@ -62,8 +79,8 @@ pub fn execute(args: &Args) -> Result<(), Error> {
}
#[cfg(feature = "color")]
fn print_line(line: &String) {
let mut stdout = StandardStream::stdout(ColorChoice::Always);
fn print_line(line: &String, color: crate::cli::ColorVariant) {
let mut stdout = StandardStream::stdout(color.into());
let color = line
.starts_with("###")
.then_some(Color::Yellow)
@ -72,8 +89,3 @@ fn print_line(line: &String) {
write!(&mut stdout, "{}", line).unwrap();
stdout.reset().ok();
}
#[cfg(not(feature = "color"))]
fn print_line(line: &String) {
print!("{}", line)
}