Merge pull request #238 from dtolnay/assets

Load custom bat theme assets
This commit is contained in:
David Tolnay 2024-10-24 00:23:03 -07:00 committed by GitHub
commit c396c12b61
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 117 additions and 5 deletions

View file

@ -77,5 +77,6 @@ jobs:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: dtolnay/install@cargo-outdated
- run: cargo tree --package bat --depth 0 | grep "^bat v$(cat src/bat.version)$"
- run: cargo update
- run: cargo outdated --workspace --exit-code 1

14
Cargo.lock generated
View file

@ -184,10 +184,13 @@ dependencies = [
"cargo-subcommand-metadata",
"clap",
"console",
"etcetera",
"fs-err",
"home",
"prettyplease",
"proc-macro2",
"quote",
"semver",
"serde",
"shlex",
"syn",
@ -343,6 +346,17 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "etcetera"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943"
dependencies = [
"cfg-if",
"home",
"windows-sys 0.48.0",
]
[[package]]
name = "fancy-regex"
version = "0.11.0"

View file

@ -21,10 +21,13 @@ bat = { version = "0.24", default-features = false, features = ["paging", "regex
cargo-subcommand-metadata = "0.1"
clap = { version = "4", features = ["deprecated", "derive"] }
console = "0.15"
etcetera = "0.8"
fs-err = "3"
home = "0.5"
prettyplease = { version = "0.2.25", features = ["verbatim"] }
proc-macro2 = "1.0.80"
quote = { version = "1.0.35", default-features = false }
semver = "1"
serde = { version = "1.0.183", features = ["derive"] }
shlex = "1.3"
syn = { version = "2.0.85", default-features = false, features = ["clone-impls", "fold", "full", "parsing", "printing", "visit-mut"] }

26
src/assets.rs Normal file
View file

@ -0,0 +1,26 @@
use crate::error::Result;
use etcetera::BaseStrategy as _;
use std::env;
use std::path::PathBuf;
use std::str;
pub const BAT_VERSION: &str = {
let mut bytes = include_str!("bat.version").as_bytes();
while let [rest @ .., b'\n' | b'\r'] = bytes {
bytes = rest;
}
if let Ok(version) = str::from_utf8(bytes) {
version
} else {
panic!()
}
};
pub fn cache_dir() -> Result<PathBuf> {
if let Some(cache_dir) = env::var_os("BAT_CACHE_PATH") {
return Ok(PathBuf::from(cache_dir));
}
let basedirs = etcetera::choose_base_strategy()?;
Ok(basedirs.cache_dir().join("bat"))
}

1
src/bat.version Normal file
View file

@ -0,0 +1 @@
0.24.0

View file

@ -8,6 +8,8 @@ pub enum Error {
TomlSer(toml::ser::Error),
TomlDe(toml::de::Error),
Quote(shlex::QuoteError),
HomeDir(etcetera::HomeDirError),
Bat(bat::error::Error),
}
pub type Result<T> = std::result::Result<T, Error>;
@ -36,6 +38,18 @@ impl From<shlex::QuoteError> for Error {
}
}
impl From<etcetera::HomeDirError> for Error {
fn from(error: etcetera::HomeDirError) -> Self {
Error::HomeDir(error)
}
}
impl From<bat::error::Error> for Error {
fn from(error: bat::error::Error) -> Self {
Error::Bat(error)
}
}
impl Display for Error {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
match self {
@ -43,6 +57,8 @@ impl Display for Error {
Error::TomlSer(e) => e.fmt(formatter),
Error::TomlDe(e) => e.fmt(formatter),
Error::Quote(e) => e.fmt(formatter),
Error::HomeDir(e) => e.fmt(formatter),
Error::Bat(e) => e.fmt(formatter),
}
}
}
@ -54,6 +70,8 @@ impl StdError for Error {
Error::TomlSer(e) => e.source(),
Error::TomlDe(e) => e.source(),
Error::Quote(e) => e.source(),
Error::HomeDir(e) => e.source(),
Error::Bat(e) => e.source(),
}
}
}

View file

@ -16,6 +16,7 @@
clippy::uninlined_format_args,
)]
mod assets;
mod cmd;
mod config;
mod edit;
@ -33,6 +34,7 @@ use crate::opts::{Coloring, Expand, Subcommand};
use crate::unparse::unparse_maximal;
use crate::version::Version;
use bat::assets::HighlightingAssets;
use bat::assets_metadata::AssetsMetadata;
use bat::config::VisibleLines;
use bat::line_range::{HighlightedLineRanges, LineRanges};
use bat::style::StyleComponents;
@ -138,9 +140,7 @@ fn do_cargo_expand() -> Result<i32> {
let config = config::deserialize();
if args.themes {
for theme in HighlightingAssets::from_binary().themes() {
let _ = writeln!(io::stdout(), "{}", theme);
}
print_themes()?;
return Ok(0);
}
@ -290,6 +290,20 @@ fn do_cargo_expand() -> Result<i32> {
};
let _ = writeln!(io::stderr());
if do_color {
let mut assets = HighlightingAssets::from_binary();
if let Some(requested_theme) = &theme {
if !assets
.themes()
.any(|supported_theme| supported_theme == requested_theme)
{
let cache_dir = assets::cache_dir()?;
if let Some(metadata) = AssetsMetadata::load_from_folder(&cache_dir)? {
if metadata.is_compatible_with(assets::BAT_VERSION) {
assets = HighlightingAssets::from_cache(&cache_dir)?;
}
}
}
}
let config = bat::config::Config {
language: Some("rust"),
show_nonprintable: false,
@ -310,10 +324,8 @@ fn do_cargo_expand() -> Result<i32> {
pager: None,
use_italic_text: false,
highlighted_lines: HighlightedLineRanges(LineRanges::none()),
use_custom_assets: false,
..Default::default()
};
let assets = HighlightingAssets::from_binary();
let controller = bat::controller::Controller::new(&config, &assets);
let inputs = vec![bat::input::Input::from_reader(Box::new(content.as_bytes()))];
// Ignore any errors.
@ -657,3 +669,40 @@ fn get_color(args: &Expand, config: &Config) -> Coloring {
Coloring::Auto // default
}
fn print_themes() -> Result<()> {
let mut cache_dir = assets::cache_dir()?;
let metadata = AssetsMetadata::load_from_folder(&cache_dir)?;
let compatible = metadata
.as_ref()
.map_or(false, |m| m.is_compatible_with(assets::BAT_VERSION));
let assets = if compatible {
HighlightingAssets::from_cache(&cache_dir)?
} else {
HighlightingAssets::from_binary()
};
for theme in assets.themes() {
let _ = writeln!(io::stdout(), "{}", theme);
}
if metadata.is_some() && !compatible {
if let Some(home_dir) = home::home_dir() {
if let Ok(relative) = cache_dir.strip_prefix(home_dir) {
cache_dir = Path::new("~").join(relative);
}
}
let bat_version = semver::Version::parse(assets::BAT_VERSION).unwrap();
let _ = writeln!(
io::stderr(),
"\nThere may be other themes in {cache_dir} but they are not \
compatible with the version of bat built into cargo-expand. Run \
`bat cache --build` with bat v{major}.{minor} to update the cache.",
cache_dir = cache_dir.display(),
major = bat_version.major,
minor = bat_version.minor,
);
}
Ok(())
}