on master help sign in
Strip dependencies of bat-as-a-library
commit570805bc985227a8e612878d8f62becd70b7b16a authorDavid Tolnay <dtolnay@gmail.com> dateMon 30 Mar 2020, 09:43 (7 years ago) parente7e1967
13 files changed+104−81
Cargo.toml+21−9 build.rs+35−31 ci/script.bash+3 src/bin/bat/app.rs−4 src/bin/bat/clap_app.rs+1−1 src/bin/bat/config.rs−2 src/bin/bat/directories.rs−1 src/bin/bat/main.rs−5 src/errors.rs+40−7 src/lib.rs−11 src/output.rs−2 src/terminal.rs−2 tests/tester.rs+4−6
Cargo.toml+21−9
@@ -15,14 +15,27 @@ exclude = [
1515build = "build.rs"
1616edition = '2018'
1717
18+[features]
19+default = ["application"]
20+# Feature required for bat the application. Should be disabled when depending on
21+# bat as a library.
22+application = [
23+ "atty",
24+ "clap",
25+ "dirs",
26+ "lazy_static",
27+ "liquid",
28+ "wild",
29+]
30+
1831[dependencies]
19−atty = "0.2.14"
32+atty = { version = "0.2.14", optional = true }
2033ansi_term = "^0.12.1"
2134ansi_colours = "^1.0"
2235console = "0.10"
23−dirs = "2.0"
24−lazy_static = "1.4"
25−wild = "2.0"
36+dirs = { version = "2.0", optional = true }
37+lazy_static = { version = "1.4", optional = true }
38+wild = { version = "2.0", optional = true }
2639content_inspector = "0.2.4"
2740encoding = "0.2"
2841shell-words = "0.1.0"
@@ -32,7 +45,6 @@ globset = "0.4"
3245[dependencies.git2]
3346version = "0.13"
3447default-features = false
35−features = []
3648
3749[dependencies.syntect]
3850version = "3.2.0"
@@ -41,22 +53,22 @@ features = ["parsing", "yaml-load", "dump-load", "dump-create"]
4153
4254[dependencies.clap]
4355version = "2.33"
56+optional = true
4457default-features = false
4558features = ["suggestions", "color", "wrap_help"]
4659
4760[dependencies.error-chain]
4861version = "0.12"
4962default-features = false
50−features = []
5163
5264[dev-dependencies]
5365tempdir = "0.3"
5466assert_cmd = "0.12.0"
5567
5668[build-dependencies]
57−clap = "2.33"
58−liquid = "0.20"
59−lazy_static = "1.4"
69+clap = { version = "2.33", optional = true }
70+liquid = { version = "0.20", optional = true }
71+lazy_static = { version = "1.4", optional = true }
6072
6173[profile.release]
6274lto = true
build.rs+35−31
@@ -1,38 +1,42 @@
11// TODO: Re-enable generation of shell completion files (below) when clap 3 is out.
22// For more details, see https://github.com/sharkdp/bat/issues/372
33
4−#[macro_use]
5−extern crate lazy_static;
6−extern crate liquid;
7−
8−use std::error::Error;
9−use std::fs;
10−use std::path::Path;
11−
12−// Read environment variables.
13−lazy_static! {
14− pub static ref PROJECT_NAME: &'static str = option_env!("PROJECT_NAME").unwrap_or("bat");
15− pub static ref PROJECT_VERSION: &'static str = option_env!("CARGO_PKG_VERSION").unwrap();
16− pub static ref EXECUTABLE_NAME: &'static str = option_env!("PROJECT_EXECUTABLE")
17− .or(option_env!("PROJECT_NAME"))
18− .unwrap_or("bat");
19−}
20−
21−/// Generates a file from a liquid template.
22−fn template(
23− variables: &liquid::Object,
24− in_file: &str,
25− out_file: impl AsRef<Path>,
26−) -> Result<(), Box<dyn Error>> {
27− let template = liquid::ParserBuilder::with_stdlib()
28− .build()?
29− .parse(&fs::read_to_string(in_file)?)?;
30−
31− fs::write(out_file, template.render(variables)?)?;
32− Ok(())
33−}
4+// For bat-as-a-library, no build script is required. The build script is for
5+// the manpage and completions, which are only relevant to the bat application.
6+#[cfg(not(feature = "application"))]
7+fn main() {}
8+
9+#[cfg(feature = "application")]
10+fn main() -> Result<(), Box<dyn std::error::Error>> {
11+ use std::error::Error;
12+ use std::fs;
13+ use std::path::Path;
14+
15+ use lazy_static::lazy_static;
16+
17+ // Read environment variables.
18+ lazy_static! {
19+ static ref PROJECT_NAME: &'static str = option_env!("PROJECT_NAME").unwrap_or("bat");
20+ static ref PROJECT_VERSION: &'static str = option_env!("CARGO_PKG_VERSION").unwrap();
21+ static ref EXECUTABLE_NAME: &'static str = option_env!("PROJECT_EXECUTABLE")
22+ .or(option_env!("PROJECT_NAME"))
23+ .unwrap_or("bat");
24+ }
25+
26+ /// Generates a file from a liquid template.
27+ fn template(
28+ variables: &liquid::Object,
29+ in_file: &str,
30+ out_file: impl AsRef<Path>,
31+ ) -> Result<(), Box<dyn Error>> {
32+ let template = liquid::ParserBuilder::with_stdlib()
33+ .build()?
34+ .parse(&fs::read_to_string(in_file)?)?;
35+
36+ fs::write(out_file, template.render(variables)?)?;
37+ Ok(())
38+ }
3439
35−fn main() -> Result<(), Box<dyn Error>> {
3640 let variables = liquid::object!({
3741 "PROJECT_NAME": PROJECT_NAME.to_owned(),
3842 "PROJECT_EXECUTABLE": EXECUTABLE_NAME.to_owned(),
ci/script.bash+3
@@ -12,3 +12,6 @@ if [[ $TARGET != arm-unknown-linux-gnueabihf ]] && [[ $TARGET != aarch64-unknown
1212 # Run 'bat' on its own source code and the README
1313 cargo run --target "$TARGET" -- src/bin/bat/main.rs README.md --paging=never
1414fi
15+
16+# Check bat-as-a-library, which has a smaller set of dependencies
17+cargo check --target "$TARGET" --verbose --lib --no-default-features
src/bin/bat/app.rs−4
@@ -9,13 +9,9 @@ use crate::{
99 config::{get_args_from_config_file, get_args_from_env_var},
1010};
1111use clap::ArgMatches;
12−use wild;
1312
1413use console::Term;
1514
16−#[cfg(windows)]
17−use ansi_term;
18−
1915use bat::{
2016 config::{
2117 Config, HighlightedLineRanges, InputFile, LineRange, LineRanges, MappingTarget, OutputWrap,
src/bin/bat/clap_app.rs+1−1
@@ -1,4 +1,4 @@
1−use clap::{App as ClapApp, AppSettings, Arg, ArgGroup, SubCommand};
1+use clap::{crate_name, crate_version, App as ClapApp, AppSettings, Arg, ArgGroup, SubCommand};
22use std::path::Path;
33
44pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
src/bin/bat/config.rs−2
@@ -4,8 +4,6 @@ use std::fs;
44use std::io::{self, Write};
55use std::path::PathBuf;
66
7−use shell_words;
8−
97use crate::directories::PROJECT_DIRS;
108
119pub fn config_file() -> PathBuf {
src/bin/bat/directories.rs−1
@@ -1,7 +1,6 @@
11use std::env;
22use std::path::{Path, PathBuf};
33
4−use dirs;
54use lazy_static::lazy_static;
65
76/// Wrapper for 'dirs' that treats MacOS more like Linux, by following the XDG specification.
src/bin/bat/main.rs−5
@@ -1,11 +1,6 @@
11// `error_chain!` can recurse deeply
22#![recursion_limit = "1024"]
33
4−#[macro_use]
5−extern crate clap;
6−
7−extern crate dirs as dirs_rs;
8−
94mod app;
105mod assets;
116mod clap_app;
src/errors.rs+40−7
@@ -2,20 +2,20 @@ use error_chain::error_chain;
22
33error_chain! {
44 foreign_links {
5− Clap(::clap::Error);
6− Io(::std::io::Error);
7− SyntectError(::syntect::LoadingError);
8− ParseIntError(::std::num::ParseIntError);
9− GlobParsingError(::globset::Error);
5+ Clap(clap::Error);
6+ Io(std::io::Error);
7+ SyntectError(syntect::LoadingError);
8+ ParseIntError(std::num::ParseIntError);
9+ GlobParsingError(globset::Error);
1010 }
1111}
1212
1313pub fn default_error_handler(error: &Error) {
1414 match error {
1515 Error(ErrorKind::Io(ref io_error), _)
16− if io_error.kind() == ::std::io::ErrorKind::BrokenPipe =>
16+ if io_error.kind() == std::io::ErrorKind::BrokenPipe =>
1717 {
18− ::std::process::exit(0);
18+ std::process::exit(0);
1919 }
2020 _ => {
2121 use ansi_term::Colour::Red;
@@ -23,3 +23,36 @@ pub fn default_error_handler(error: &Error) {
2323 }
2424 };
2525}
26+
27+// Mock out a type for clap::Error if we aren't pulling in a dependency on clap.
28+//
29+// This can be removed after migrating away from error_chain to some modern
30+// derive-based error library such as thiserror, in favor of:
31+//
32+// #[derive(Error)]
33+// pub enum Error {
34+// #[cfg(feature = "application")]
35+// Clap(clap::Error),
36+// ...
37+// }
38+//
39+#[cfg(not(feature = "application"))]
40+mod clap {
41+ use std::fmt::{self, Debug, Display};
42+
43+ pub struct Error(());
44+
45+ impl Display for Error {
46+ fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result {
47+ unreachable!()
48+ }
49+ }
50+
51+ impl Debug for Error {
52+ fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result {
53+ unreachable!()
54+ }
55+ }
56+
57+ impl std::error::Error for Error {}
58+}
src/lib.rs−11
@@ -1,17 +1,6 @@
11// `error_chain!` can recurse deeply
22#![recursion_limit = "1024"]
33
4−extern crate ansi_term;
5−extern crate atty;
6−extern crate console;
7−extern crate content_inspector;
8−extern crate dirs as dirs_rs;
9−extern crate encoding;
10−extern crate git2;
11−extern crate shell_words;
12−extern crate syntect;
13−extern crate wild;
14−
154pub(crate) mod assets;
165pub mod config;
176pub(crate) mod controller;
src/output.rs−2
@@ -4,8 +4,6 @@ use std::io::{self, Write};
44use std::path::PathBuf;
55use std::process::{Child, Command, Stdio};
66
7−use shell_words;
8−
97use crate::config::PagingMode;
108use crate::errors::*;
119use crate::less::retrieve_less_version;
src/terminal.rs−2
@@ -1,5 +1,3 @@
1−extern crate ansi_colours;
2−
31use ansi_term::Colour::{Fixed, RGB};
42use ansi_term::{self, Style};
53
tests/tester.rs+4−6
@@ -4,13 +4,11 @@ use std::io::Read;
44use std::path::{Path, PathBuf};
55use std::process::Command;
66
7−extern crate tempdir;
8−use self::tempdir::TempDir;
7+use tempdir::TempDir;
98
10−extern crate git2;
11−use self::git2::build::CheckoutBuilder;
12−use self::git2::Repository;
13−use self::git2::Signature;
9+use git2::build::CheckoutBuilder;
10+use git2::Repository;
11+use git2::Signature;
1412
1513pub struct BatTester {
1614 /// Temporary working directory