From 194ab029c16a6b9ec7cdb4b60f66168dd1f51675 Mon Sep 17 00:00:00 2001 From: Andrew Gallant Date: Mon, 5 Feb 2018 19:22:44 -0500 Subject: [PATCH 1/4] argv: update clap to 2.29.4 We use the new AppSettings::AllArgsOverrideSelf to permit all flags to be specified multiple times. This removes the need for our previous work-around where we would enable `multiple` for every flag and then just extract the last value when consuming clap's matches. We also add a couple regression tests that ensure repeated switches and flags work as expected. --- Cargo.lock | 12 ++++++------ Cargo.toml | 6 +++--- src/app.rs | 9 +++------ src/args.rs | 4 ++-- tests/tests.rs | 43 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 57 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d50280fd8..3acd8c314 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,13 +41,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "clap" -version = "2.29.2" +version = "2.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -218,7 +218,7 @@ version = "0.7.1" dependencies = [ "atty 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "bytecount 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.29.2 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.29.4 (registry+https://github.com/rust-lang/crates.io-index)", "encoding_rs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "globset 0.2.1", "grep 0.1.7", @@ -250,7 +250,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "strsim" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -360,7 +360,7 @@ dependencies = [ "checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" "checksum bytecount 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "882585cd7ec84e902472df34a5e01891202db3bf62614e1f0afe459c1afcf744" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" -"checksum clap 2.29.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4151c5790817c7d21bbdc6c3530811f798172915f93258244948b93ba19604a6" +"checksum clap 2.29.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7b8f59bcebcfe4269b09f71dab0da15b355c75916a8f975d3876ce81561893ee" "checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19" "checksum encoding_rs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f5215aabf22b83153be3ee44dfe3f940214541b2ce13d419c55e7a115c8c51a9" "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" @@ -380,7 +380,7 @@ dependencies = [ "checksum regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8e931c58b93d86f080c734bfd2bce7dd0079ae2331235818133c8be7f422e20e" "checksum same-file 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3257af0472da4b8b8902102a57bafffd9991f0f43772a8af6153d597e6e4ae2" "checksum simd 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3dd0805c7363ab51a829a1511ad24b6ed0349feaa756c4bc2f977f9f496e6673" -"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694" +"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" "checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" "checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693" diff --git a/Cargo.toml b/Cargo.toml index b36bac889..c7c9dfa3b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ name = "integration" path = "tests/tests.rs" [workspace] -members = [ "grep", "globset", "ignore", "termcolor", "wincolor" ] +members = ["grep", "globset", "ignore", "termcolor", "wincolor"] [dependencies] atty = "0.2.2" @@ -50,7 +50,7 @@ termcolor = { version = "0.3.3", path = "termcolor" } globset = { version = "0.2.1", path = "globset" } [dependencies.clap] -version = "2.26" +version = "2.29.4" default-features = false features = ["suggestions", "color"] @@ -62,7 +62,7 @@ features = ["std", "winnt"] lazy_static = "1" [build-dependencies.clap] -version = "2.26" +version = "2.29.4" default-features = false features = ["suggestions", "color"] diff --git a/src/app.rs b/src/app.rs index ba1418946..05f411ac7 100644 --- a/src/app.rs +++ b/src/app.rs @@ -67,6 +67,7 @@ pub fn app() -> App<'static, 'static> { .about(ABOUT) .max_term_width(100) .setting(AppSettings::UnifiedHelpMessage) + .setting(AppSettings::AllArgsOverrideSelf) .usage(USAGE) .template(TEMPLATE) .help_message("Prints help information. Use --help for more details."); @@ -250,8 +251,7 @@ impl RGArg { /// inspect the number of times the switch is used. fn switch(long_name: &'static str) -> RGArg { let claparg = Arg::with_name(long_name) - .long(long_name) - .multiple(true); + .long(long_name); RGArg { claparg: claparg, name: long_name, @@ -280,7 +280,6 @@ impl RGArg { .long(long_name) .value_name(value_name) .takes_value(true) - .multiple(true) .number_of_values(1); RGArg { claparg: claparg, @@ -351,11 +350,8 @@ impl RGArg { // document it distinct for each different kind. See RGArgKind docs. match self.kind { RGArgKind::Positional { ref mut multiple, .. } => { - self.claparg = self.claparg.multiple(true); *multiple = true; } - // We don't need to modify clap's state in the following cases - // because all switches and flags always have `multiple` enabled. RGArgKind::Switch { ref mut multiple, .. } => { *multiple = true; } @@ -363,6 +359,7 @@ impl RGArg { *multiple = true; } } + self.claparg = self.claparg.multiple(true); self } diff --git a/src/args.rs b/src/args.rs index d0990fdc0..0c25727f7 100644 --- a/src/args.rs +++ b/src/args.rs @@ -994,7 +994,7 @@ impl<'a> ArgMatches<'a> { } fn value_of_lossy(&self, name: &str) -> Option { - self.values_of_lossy(name).and_then(|mut vals| vals.pop()) + self.0.value_of_lossy(name).map(|s| s.into_owned()) } fn values_of_lossy(&self, name: &str) -> Option> { @@ -1002,7 +1002,7 @@ impl<'a> ArgMatches<'a> { } fn value_of_os(&'a self, name: &str) -> Option<&'a OsStr> { - self.values_of_os(name).and_then(|it| it.last()) + self.0.value_of_os(name) } fn values_of_os(&'a self, name: &str) -> Option> { diff --git a/tests/tests.rs b/tests/tests.rs index ecc840e79..e88756dce 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -1166,6 +1166,49 @@ clean!(regression_493, " 're ", "input.txt", |wd: WorkDir, mut cmd: Command| { assert_eq!(lines, " 're \n"); }); +// See: https://github.com/BurntSushi/ripgrep/issues/553 +sherlock!(regression_553_switch, "sherlock", ".", +|wd: WorkDir, mut cmd: Command| { + cmd.arg("-i"); + let lines: String = wd.stdout(&mut cmd); + let expected = "\ +sherlock:For the Doctor Watsons of this world, as opposed to the Sherlock +sherlock:be, to a very large extent, the result of luck. Sherlock Holmes +"; + assert_eq!(lines, expected); + + // This repeats the `-i` flag. + cmd.arg("-i"); + let lines: String = wd.stdout(&mut cmd); + let expected = "\ +sherlock:For the Doctor Watsons of this world, as opposed to the Sherlock +sherlock:be, to a very large extent, the result of luck. Sherlock Holmes +"; + assert_eq!(lines, expected); +}); + +sherlock!(regression_553_flag, "world|attached", +|wd: WorkDir, mut cmd: Command| { + cmd.arg("-C").arg("1"); + let lines: String = wd.stdout(&mut cmd); + let expected = "\ +For the Doctor Watsons of this world, as opposed to the Sherlock +Holmeses, success in the province of detective work must always +-- +but Doctor Watson has to have it taken out for him and dusted, +and exhibited clearly, with a label attached. +"; + assert_eq!(lines, expected); + + cmd.arg("-C").arg("0"); + let lines: String = wd.stdout(&mut cmd); + let expected = "\ +For the Doctor Watsons of this world, as opposed to the Sherlock +and exhibited clearly, with a label attached. +"; + assert_eq!(lines, expected); +}); + // See: https://github.com/BurntSushi/ripgrep/issues/599 clean!(regression_599, "^$", "input.txt", |wd: WorkDir, mut cmd: Command| { wd.create("input.txt", "\n\ntest\n"); From 412a2a90b25a9cbbc6f075e2cb210a926c7db108 Mon Sep 17 00:00:00 2001 From: Andrew Gallant Date: Sun, 4 Feb 2018 11:41:06 -0500 Subject: [PATCH 2/4] argv: tweak the meaning of zero This commit makes a small tweak to the --max-columns flag. Namely, if the value of the flag is 0, then ripgrep behaves as-if the flag were absent. This is useful in the context of ripgrep reading configuration from the environment. For example, an end user might set --max-columns=150, but we should permit the user to disable this setting when needed. Using -M0 is a nice way to do that. We do this because a zero value for --max-columns isn't particularly meaningful. We do leave the --max-count, --max-filesize and --maxdepth flags alone though, since a zero value for those flags is potentially meaningful. (--max-count even has tests for ripgrep's behavior when given a value of 0.) --- src/app.rs | 2 ++ src/args.rs | 22 ++++++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/app.rs b/src/app.rs index 05f411ac7..3591dc222 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1034,6 +1034,8 @@ fn flag_max_columns(args: &mut Vec) { const LONG: &str = long!("\ Don't print lines longer than this limit in bytes. Longer lines are omitted, and only the number of matches in that line is printed. + +When this flag is omitted or is set to 0, then it has no effect. "); let arg = RGArg::flag("max-columns", "NUM").short("M") .help(SHORT).long_help(LONG) diff --git a/src/args.rs b/src/args.rs index 0c25727f7..0461261bc 100644 --- a/src/args.rs +++ b/src/args.rs @@ -381,8 +381,8 @@ impl<'a> ArgMatches<'a> { line_number: line_number, line_number_width: try!(self.usize_of("line-number-width")), line_per_match: self.is_present("vimgrep"), - max_columns: self.usize_of("max-columns")?, - max_count: self.usize_of("max-count")?.map(|max| max as u64), + max_columns: self.usize_of_nonzero("max-columns")?, + max_count: self.usize_of("max-count")?.map(|n| n as u64), max_filesize: self.max_filesize()?, maxdepth: self.usize_of("maxdepth")?, mmap: mmap, @@ -971,6 +971,24 @@ impl<'a> ArgMatches<'a> { self.values_of_lossy(name).unwrap_or_else(Vec::new) } + /// Safely reads an arg value with the given name, and if it's present, + /// tries to parse it as a usize value. + /// + /// If the number is zero, then it is considered absent and `None` is + /// returned. + fn usize_of_nonzero(&self, name: &str) -> Result> { + match self.value_of_lossy(name) { + None => Ok(None), + Some(v) => v.parse().map_err(From::from).map(|n| { + if n == 0 { + None + } else { + Some(n) + } + }), + } + } + /// Safely reads an arg value with the given name, and if it's present, /// tries to parse it as a usize value. fn usize_of(&self, name: &str) -> Result> { From b8748355e7bcf552510bbc837c8ce55311cfa385 Mon Sep 17 00:00:00 2001 From: Andrew Gallant Date: Sun, 4 Feb 2018 12:14:38 -0500 Subject: [PATCH 3/4] ci: cleanup This cleans up our CI scripts but doesn't significantly change anything. Mostly this is removing dead code and wrong comments, and making the style a bit more consistent. --- .travis.yml | 51 +++++++++++++++------------------------------ ci/before_deploy.sh | 31 +++++++++++++-------------- ci/install.sh | 38 +++++++++++++-------------------- ci/script.sh | 18 ++++------------ ci/sha256.sh | 0 ci/utils.sh | 29 +++++++------------------- 6 files changed, 58 insertions(+), 109 deletions(-) mode change 100644 => 100755 ci/before_deploy.sh mode change 100644 => 100755 ci/install.sh mode change 100644 => 100755 ci/script.sh mode change 100644 => 100755 ci/sha256.sh diff --git a/.travis.yml b/.travis.yml index ee46cd7cf..bf2b3f555 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,9 @@ language: rust cache: cargo - env: global: - - PROJECT_NAME=ripgrep + - PROJECT_NAME: ripgrep - RUST_BACKTRACE: full - addons: apt: packages: @@ -13,13 +11,12 @@ addons: - zsh # Needed for testing decompression search. - xz-utils - matrix: fast_finish: true include: # Nightly channel. - # (All *nix releases are done on the nightly channel to take advantage - # of the regex library's multiple pattern SIMD search.) + # All *nix releases are done on the nightly channel to take advantage + # of the regex library's multiple pattern SIMD search. - os: linux rust: nightly env: TARGET=i686-unknown-linux-musl @@ -39,14 +36,16 @@ matrix: - binutils-arm-linux-gnueabihf - libc6-armhf-cross - libc6-dev-armhf-cross - # Beta channel. + # Beta channel. We enable these to make sure there are no regressions in + # Rust beta releases. - os: linux rust: beta env: TARGET=x86_64-unknown-linux-musl - os: linux rust: beta env: TARGET=x86_64-unknown-linux-gnu - # Minimum Rust supported channel. + # Minimum Rust supported channel. We enable these to make sure ripgrep + # continues to work on the advertised minimum Rust version. - os: linux rust: 1.20.0 env: TARGET=x86_64-unknown-linux-gnu @@ -63,43 +62,27 @@ matrix: - binutils-arm-linux-gnueabihf - libc6-armhf-cross - libc6-dev-armhf-cross - -before_install: - - export PATH="$PATH:$HOME/.cargo/bin" - -install: - - bash ci/install.sh - -script: - - bash ci/script.sh - -before_deploy: - - bash ci/before_deploy.sh - +install: ci/install.sh +script: ci/script.sh +before_deploy: ci/before_deploy.sh deploy: provider: releases - api_key: - secure: "IbSnsbGkxSydR/sozOf1/SRvHplzwRUHzcTjM7BKnr7GccL86gRPUrsrvD103KjQUGWIc1TnK1YTq5M0Onswg/ORDjqa1JEJPkPdPnVh9ipbF7M2De/7IlB4X4qXLKoApn8+bx2x/mfYXu4G+G1/2QdbaKK2yfXZKyjz0YFx+6CNrVCT2Nk8q7aHvOOzAL58vsG8iPDpupuhxlMDDn/UhyOWVInmPPQ0iJR1ZUJN8xJwXvKvBbfp3AhaBiAzkhXHNLgBR8QC5noWWMXnuVDMY3k4f3ic0V+p/qGUCN/nhptuceLxKFicMCYObSZeUzE5RAI0/OBW7l3z2iCoc+TbAnn+JrX/ObJCfzgAOXAU3tLaBFMiqQPGFKjKg1ltSYXomOFP/F7zALjpvFp4lYTBajRR+O3dqaxA9UQuRjw27vOeUpMcga4ZzL4VXFHzrxZKBHN//XIGjYAVhJ1NSSeGpeJV5/+jYzzWKfwSagRxQyVCzMooYFFXzn8Yxdm3PJlmp3GaAogNkdB9qKcrEvRINCelalzALPi0hD/HUDi8DD2PNTCLLMo6VSYtvc685Zbe+KgNzDV1YyTrRCUW6JotrS0r2ULLwnsh40hSB//nNv3XmwNmC/CmW5QAnIGj8cBMF4S2t6ohADIndojdAfNiptmaZOIT6owK7bWMgPMyopo=" file_glob: true - file: ${PROJECT_NAME}-${TRAVIS_TAG}-${TARGET}.* - # don't delete the artifacts from previous phases + file: deployment/${PROJECT_NAME}-${TRAVIS_TAG}-${TARGET}.* skip_cleanup: true - # deploy when a new tag is pushed on: - # channel to use to produce the release artifacts - # NOTE make sure you only release *once* per target - # TODO you may want to pick a different channel condition: $TRAVIS_RUST_VERSION = nightly - tags: true - + branch: ag/misc-improvements + # tags: true + api_key: + secure: "IbSnsbGkxSydR/sozOf1/SRvHplzwRUHzcTjM7BKnr7GccL86gRPUrsrvD103KjQUGWIc1TnK1YTq5M0Onswg/ORDjqa1JEJPkPdPnVh9ipbF7M2De/7IlB4X4qXLKoApn8+bx2x/mfYXu4G+G1/2QdbaKK2yfXZKyjz0YFx+6CNrVCT2Nk8q7aHvOOzAL58vsG8iPDpupuhxlMDDn/UhyOWVInmPPQ0iJR1ZUJN8xJwXvKvBbfp3AhaBiAzkhXHNLgBR8QC5noWWMXnuVDMY3k4f3ic0V+p/qGUCN/nhptuceLxKFicMCYObSZeUzE5RAI0/OBW7l3z2iCoc+TbAnn+JrX/ObJCfzgAOXAU3tLaBFMiqQPGFKjKg1ltSYXomOFP/F7zALjpvFp4lYTBajRR+O3dqaxA9UQuRjw27vOeUpMcga4ZzL4VXFHzrxZKBHN//XIGjYAVhJ1NSSeGpeJV5/+jYzzWKfwSagRxQyVCzMooYFFXzn8Yxdm3PJlmp3GaAogNkdB9qKcrEvRINCelalzALPi0hD/HUDi8DD2PNTCLLMo6VSYtvc685Zbe+KgNzDV1YyTrRCUW6JotrS0r2ULLwnsh40hSB//nNv3XmwNmC/CmW5QAnIGj8cBMF4S2t6ohADIndojdAfNiptmaZOIT6owK7bWMgPMyopo=" branches: only: # Pushes and PR to the master branch - master - # IMPORTANT Ruby regex to match tags. Required, or travis won't trigger deploys when a new tag - # is pushed. This regex matches semantic versions like v1.2.3-rc4+2016.02.22 + # Ruby regex to match tags. Required, or travis won't trigger deploys when + # a new tag is pushed. - /^\d+\.\d+\.\d+.*$/ - notifications: email: on_success: never diff --git a/ci/before_deploy.sh b/ci/before_deploy.sh old mode 100644 new mode 100755 index 4890f96bc..35bdc0b1d --- a/ci/before_deploy.sh +++ b/ci/before_deploy.sh @@ -1,40 +1,39 @@ -# `before_deploy` phase: here we package the build artifacts +#!/bin/bash + +# package the build artifacts set -ex -. $(dirname $0)/utils.sh +. "$(dirname $0)/utils.sh" # Generate artifacts for release mk_artifacts() { if is_ssse3_target; then RUSTFLAGS="-C target-feature=+ssse3" \ - cargo build --target $TARGET --release --features simd-accel + cargo build --target "$TARGET" --release --features simd-accel else - cargo build --target $TARGET --release + cargo build --target "$TARGET" --release fi } mk_tarball() { - # create a "staging" directory - local td=$(mktempd) - local out_dir=$(pwd) - local name="${PROJECT_NAME}-${TRAVIS_TAG}-${TARGET}" local gcc_prefix="$(gcc_prefix)" - mkdir "${td:?}/${name}" - mkdir "$td/$name/complete" + local td="$(mktemp -d)" + local name="${PROJECT_NAME}-${TRAVIS_TAG}-${TARGET}" + mkdir -p "$td/$name/complete" + mkdir deployment + local out_dir="$(pwd)/deployment" cp target/$TARGET/release/rg "$td/$name/rg" - ${gcc_prefix}strip "$td/$name/rg" + "${gcc_prefix}strip" "$td/$name/rg" cp {doc/rg.1,README.md,UNLICENSE,COPYING,LICENSE-MIT} "$td/$name/" cp \ - target/$TARGET/release/build/ripgrep-*/out/{rg.bash-completion,rg.fish,_rg.ps1} \ + target/"$TARGET"/release/build/ripgrep-*/out/{rg.bash,rg.fish,_rg.ps1} \ "$td/$name/complete/" cp complete/_rg "$td/$name/complete/" - pushd $td - tar czf "$out_dir/$name.tar.gz" * - popd - rm -r $td + (cd "$td" && tar czf "$out_dir/$name.tar.gz" *) + rm -rf "$td" } main() { diff --git a/ci/install.sh b/ci/install.sh old mode 100644 new mode 100755 index ffddf866b..08d65b1ae --- a/ci/install.sh +++ b/ci/install.sh @@ -1,29 +1,22 @@ -# `install` phase: install stuff needed for the `script` phase +#!/bin/bash + +# install stuff needed for the `script` phase + +# Where rustup gets installed. +export PATH="$PATH:$HOME/.cargo/bin" set -ex -. $(dirname $0)/utils.sh - -install_c_toolchain() { - case $TARGET in - aarch64-unknown-linux-gnu) - sudo apt-get install -y --no-install-recommends \ - gcc-aarch64-linux-gnu libc6-arm64-cross libc6-dev-arm64-cross - ;; - *) - # For other targets, this is handled by addons.apt.packages in .travis.yml - ;; - esac -} +. "$(dirname $0)/utils.sh" install_rustup() { - curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain=$TRAVIS_RUST_VERSION - + curl https://sh.rustup.rs -sSf \ + | sh -s -- -y --default-toolchain="$TRAVIS_RUST_VERSION" rustc -V cargo -V } -install_standard_crates() { +install_targets() { if [ $(host) != "$TARGET" ]; then rustup target add $TARGET fi @@ -33,11 +26,13 @@ configure_cargo() { local prefix=$(gcc_prefix) if [ -n "${prefix}" ]; then local gcc_suffix= - test -n "${GCC_VERSION}" && gcc_suffix="-${GCC_VERSION}" || : + if [ -n "$GCC_VERSION" ]; then + gcc_suffix="-$GCC_VERSION" + fi local gcc="${prefix}gcc${gcc_suffix}" # information about the cross compiler - ${gcc} -v + "${gcc}" -v # tell cargo which linker to use for cross compilation mkdir -p .cargo @@ -49,12 +44,9 @@ EOF } main() { - install_c_toolchain install_rustup - install_standard_crates + install_targets configure_cargo - - # TODO if you need to install extra stuff add it here } main diff --git a/ci/script.sh b/ci/script.sh old mode 100644 new mode 100755 index 32aef0035..e9f9bcb36 --- a/ci/script.sh +++ b/ci/script.sh @@ -1,19 +1,10 @@ -# `script` phase: you usually build, test and generate docs in this phase +#!/bin/bash + +# build, test and generate docs in this phase set -ex -. $(dirname $0)/utils.sh - -# NOTE Workaround for rust-lang/rust#31907 - disable doc tests when cross compiling -# This has been fixed in the nightly channel but it would take a while to reach the other channels -disable_cross_doctests() { - if [ $(host) != "$TARGET" ] && [ "$TRAVIS_RUST_VERSION" = "stable" ]; then - if [ "$TRAVIS_OS_NAME" = "osx" ]; then - brew install gnu-sed --default-names - fi - find src -name '*.rs' -type f | xargs sed -i -e 's:\(//.\s*```\):\1 ignore,:g' - fi -} +. "$(dirname $0)/utils.sh" main() { # disable_cross_doctests @@ -22,7 +13,6 @@ main() { cargo test --target "${TARGET}" --verbose --all "$( dirname "${0}" )/test_complete.sh" fi - # sanity check the file type file target/$TARGET/debug/rg } diff --git a/ci/sha256.sh b/ci/sha256.sh old mode 100644 new mode 100755 diff --git a/ci/utils.sh b/ci/utils.sh index 7dcd7cecf..61428ecba 100644 --- a/ci/utils.sh +++ b/ci/utils.sh @@ -1,6 +1,6 @@ -mktempd() { - echo $(mktemp -d 2>/dev/null || mktemp -d -t tmp) -} +#!/bin/bash + +# Various utility functions used through CI. host() { case "$TRAVIS_OS_NAME" in @@ -15,9 +15,6 @@ host() { gcc_prefix() { case "$TARGET" in - aarch64-unknown-linux-gnu) - echo aarch64-linux-gnu- - ;; arm*-gnueabihf) echo arm-linux-gnueabihf- ;; @@ -27,19 +24,8 @@ gcc_prefix() { esac } -dobin() { - [ -z $MAKE_DEB ] && die 'dobin: $MAKE_DEB not set' - [ $# -lt 1 ] && die "dobin: at least one argument needed" - - local f prefix=$(gcc_prefix) - for f in "$@"; do - install -m0755 $f $dtd/debian/usr/bin/ - ${prefix}strip -s $dtd/debian/usr/bin/$(basename $f) - done -} - architecture() { - case ${TARGET:?} in + case "$TARGET" in x86_64-*) echo amd64 ;; @@ -56,9 +42,8 @@ architecture() { } is_ssse3_target() { - case "${TARGET}" in - i686-unknown-netbsd) return 1 ;; # i686-unknown-netbsd - SSE2 - i686*|x86_64*) return 0 ;; + case "$TARGET" in + x86_64*) return 0 ;; + *) return 1 ;; esac - return 1 } From a2fc8d8b34c55822fb9781539485d3526548567f Mon Sep 17 00:00:00 2001 From: Andrew Gallant Date: Mon, 5 Feb 2018 18:45:45 -0500 Subject: [PATCH 4/4] doc: generate man page This commit uses the recent refactoring for defining flags to automatically generate a man page. This finally allows us to define the documentation for each flag in a single place. The man page is generated on every build, if and only if `asciidoc` is installed. When generated, it is placed in Cargo's `OUT_DIR` directory, which is the same place that shell completions live. --- .travis.yml | 2 + build.rs | 128 +++++++- ci/before_deploy.sh | 22 +- doc/convert-to-man | 5 - doc/rg.1 | 692 -------------------------------------------- doc/rg.1.md | 456 ----------------------------- doc/rg.1.txt.tpl | 136 +++++++++ src/app.rs | 25 +- 8 files changed, 292 insertions(+), 1174 deletions(-) delete mode 100755 doc/convert-to-man delete mode 100644 doc/rg.1 delete mode 100644 doc/rg.1.md create mode 100644 doc/rg.1.txt.tpl diff --git a/.travis.yml b/.travis.yml index bf2b3f555..aaaa3dd1d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,8 @@ addons: - zsh # Needed for testing decompression search. - xz-utils + # For generating man page. + - asciidoc matrix: fast_finish: true include: diff --git a/build.rs b/build.rs index 01b3d18ef..93c258589 100644 --- a/build.rs +++ b/build.rs @@ -4,11 +4,15 @@ extern crate clap; extern crate lazy_static; use std::env; -use std::fs; +use std::fs::{self, File}; +use std::io::{self, Read, Write}; +use std::path::Path; use std::process; use clap::Shell; +use app::{RGArg, RGArgKind}; + #[allow(dead_code)] #[path = "src/app.rs"] mod app; @@ -27,6 +31,9 @@ fn main() { } }; fs::create_dir_all(&outdir).unwrap(); + if let Err(err) = generate_man_page(&outdir) { + eprintln!("failed to generate man page: {}", err); + } // Use clap to build completion files. let mut app = app::app(); @@ -37,11 +44,124 @@ fn main() { // are manually maintained in `complete/_rg`. // Make the current git hash available to the build. + if let Some(rev) = git_revision_hash() { + println!("cargo:rustc-env=RIPGREP_BUILD_GIT_HASH={}", rev); + } +} + +fn git_revision_hash() -> Option { let result = process::Command::new("git") .args(&["rev-parse", "--short=10", "HEAD"]) .output(); - if let Ok(output) = result { - let hash = String::from_utf8_lossy(&output.stdout); - println!("cargo:rustc-env=RIPGREP_BUILD_GIT_HASH={}", hash); + result.ok().map(|output| { + String::from_utf8_lossy(&output.stdout).trim().to_string() + }) +} + +fn generate_man_page>(outdir: P) -> io::Result<()> { + // If asciidoc isn't installed, then don't do anything. + if let Err(err) = process::Command::new("a2x").output() { + eprintln!("Could not run 'a2x' binary, skipping man page generation."); + eprintln!("Error from running 'a2x': {}", err); + return Ok(()); + } + let outdir = outdir.as_ref(); + let cwd = env::current_dir()?; + let tpl_path = cwd.join("doc").join("rg.1.txt.tpl"); + let txt_path = outdir.join("rg.1.txt"); + + let mut tpl = String::new(); + File::open(&tpl_path)?.read_to_string(&mut tpl)?; + tpl = tpl.replace("{OPTIONS}", &formatted_options()?); + + let githash = git_revision_hash(); + let githash = githash.as_ref().map(|x| &**x); + tpl = tpl.replace("{VERSION}", &app::long_version(githash)); + + File::create(&txt_path)?.write_all(tpl.as_bytes())?; + let result = process::Command::new("a2x") + .arg("--no-xmllint") + .arg("--doctype").arg("manpage") + .arg("--format").arg("manpage") + .arg(&txt_path) + .spawn()? + .wait()?; + if !result.success() { + let msg = format!("'a2x' failed with exit code {:?}", result.code()); + return Err(ioerr(msg)); + } + Ok(()) +} + +fn formatted_options() -> io::Result { + let mut args = app::all_args_and_flags(); + args.sort_by(|x1, x2| x1.name.cmp(&x2.name)); + + let mut formatted = vec![]; + for arg in args { + // ripgrep only has two positional arguments, and probably will only + // ever have two positional arguments, so we just hardcode them into + // the template. + if let app::RGArgKind::Positional{..} = arg.kind { + continue; + } + formatted.push(formatted_arg(&arg)?); } + Ok(formatted.join("\n\n")) +} + +fn formatted_arg(arg: &RGArg) -> io::Result { + match arg.kind { + RGArgKind::Positional{..} => panic!("unexpected positional argument"), + RGArgKind::Switch { long, short, multiple } => { + let mut out = vec![]; + + let mut header = format!("--{}", long); + if let Some(short) = short { + header = format!("-{}, {}", short, header); + } + if multiple { + header = format!("*{}* ...::", header); + } else { + header = format!("*{}*::", header); + } + writeln!(out, "{}", header)?; + writeln!(out, "{}", formatted_doc_txt(arg)?)?; + + Ok(String::from_utf8(out).unwrap()) + } + RGArgKind::Flag { long, short, value_name, multiple, .. } => { + let mut out = vec![]; + + let mut header = format!("--{}", long); + if let Some(short) = short { + header = format!("-{}, {}", short, header); + } + if multiple { + header = format!("*{}* _{}_ ...::", header, value_name); + } else { + header = format!("*{}* _{}_::", header, value_name); + } + writeln!(out, "{}", header)?; + writeln!(out, "{}", formatted_doc_txt(arg)?)?; + + Ok(String::from_utf8(out).unwrap()) + } + } +} + +fn formatted_doc_txt(arg: &RGArg) -> io::Result { + let paragraphs: Vec<&str> = arg.doc_long.split("\n\n").collect(); + if paragraphs.is_empty() { + return Err(ioerr(format!("missing docs for --{}", arg.name))); + } + let first = format!(" {}", paragraphs[0].replace("\n", "\n ")); + if paragraphs.len() == 1 { + return Ok(first); + } + Ok(format!("{}\n+\n{}", first, paragraphs[1..].join("\n+\n"))) +} + +fn ioerr(msg: String) -> io::Error { + io::Error::new(io::ErrorKind::Other, msg) } diff --git a/ci/before_deploy.sh b/ci/before_deploy.sh index 35bdc0b1d..bef04122a 100755 --- a/ci/before_deploy.sh +++ b/ci/before_deploy.sh @@ -20,17 +20,25 @@ mk_tarball() { local gcc_prefix="$(gcc_prefix)" local td="$(mktemp -d)" local name="${PROJECT_NAME}-${TRAVIS_TAG}-${TARGET}" - mkdir -p "$td/$name/complete" - mkdir deployment + local staging="$td/$name" + mkdir -p "$staging/complete" local out_dir="$(pwd)/deployment" - - cp target/$TARGET/release/rg "$td/$name/rg" - "${gcc_prefix}strip" "$td/$name/rg" - cp {doc/rg.1,README.md,UNLICENSE,COPYING,LICENSE-MIT} "$td/$name/" + mkdir -p "$out_dir" + + # Copy the ripgrep binary and strip it. + cp target/$TARGET/release/rg "$staging/rg" + "${gcc_prefix}strip" "$staging/rg" + # Copy the README and licenses. + cp {README.md,UNLICENSE,COPYING,LICENSE-MIT} "$staging/" + # Copy shell completion files. cp \ target/"$TARGET"/release/build/ripgrep-*/out/{rg.bash,rg.fish,_rg.ps1} \ - "$td/$name/complete/" + "$staging/complete/" cp complete/_rg "$td/$name/complete/" + # Copy man page. + cp \ + target/"$TARGET"/release/build/ripgrep-*/out/rg.1 \ + "$td/$name/" (cd "$td" && tar czf "$out_dir/$name.tar.gz" *) rm -rf "$td" diff --git a/doc/convert-to-man b/doc/convert-to-man deleted file mode 100755 index 60761dbad..000000000 --- a/doc/convert-to-man +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -e - -pandoc -s -f markdown-smart -t man rg.1.md -o rg.1 -sed -i.bak 's/\.TH.*/.TH "rg" "1"/g' rg.1 -rm -f rg.1.bak # BSD `sed` requires the creation of a back-up file diff --git a/doc/rg.1 b/doc/rg.1 deleted file mode 100644 index b81124632..000000000 --- a/doc/rg.1 +++ /dev/null @@ -1,692 +0,0 @@ -.\" Automatically generated by Pandoc 2.0.6 -.\" -.TH "rg" "1" -.hy -.SH NAME -.PP -rg \- recursively search current directory for lines matching a pattern -.SH SYNOPSIS -.PP -rg [\f[I]OPTIONS\f[]] \f[I]PATTERN\f[] [\f[I]PATH\f[] ...] -.PP -rg [\f[I]OPTIONS\f[]] [\-e \f[I]PATTERN\f[] ...] [\-f \f[I]FILE\f[] ...] -[\f[I]PATH\f[] ...] -.PP -rg [\f[I]OPTIONS\f[]] \-\-files [\f[I]PATH\f[] ...] -.PP -rg [\f[I]OPTIONS\f[]] \-\-type\-list -.PP -rg [\f[I]OPTIONS\f[]] \-\-help -.PP -rg [\f[I]OPTIONS\f[]] \-\-version -.SH DESCRIPTION -.PP -ripgrep (rg) combines the usability of The Silver Searcher (an ack -clone) with the raw speed of grep. -.PP -ripgrep\[aq]s regex engine uses finite automata and guarantees linear -time searching. -Because of this, features like backreferences and arbitrary lookaround -are not supported. -.PP -Note that ripgrep may abort unexpectedly when using default settings if -it searches a file that is simultaneously truncated. -This behavior can be avoided by passing the \-\-no\-mmap flag. -.PP -Project home page: https://github.com/BurntSushi/ripgrep -.SH POSITIONAL ARGUMENTS -.TP -.B \f[I]PATTERN\f[] -A regular expression used for searching. -To match a pattern beginning with a dash, use the \-e/\-\-regexp option. -.RS -.RE -.TP -.B \f[I]PATH\f[] -A file or directory to search. -Directories are searched recursively. -Paths specified expicitly on the command line override glob and ignore -rules. -.RS -.RE -.SH COMMON OPTIONS -.TP -.B \-a, \-\-text -Search binary files as if they were text. -.RS -.RE -.TP -.B \-c, \-\-count -Only show count of line matches for each file. -.RS -.RE -.TP -.B \-\-color \f[I]WHEN\f[] -Whether to use color in the output. -Valid values are never, auto, always or ansi. -The default is auto. -When always is used, coloring is attempted based on your environment. -When ansi is used, coloring is forcefully done using ANSI escape color -codes. -.RS -.RE -.TP -.B \-e, \-\-regexp \f[I]PATTERN\f[] ... -Use PATTERN to search. -This option can be provided multiple times, where all patterns given are -searched. -This is also useful when searching for patterns that start with a dash. -.RS -.RE -.TP -.B \-F, \-\-fixed\-strings -Treat the pattern as a literal string instead of a regular expression. -.RS -.RE -.TP -.B \-g, \-\-glob \f[I]GLOB\f[] ... -Include or exclude files for searching that match the given glob. -This always overrides any other ignore logic if there is a conflict, but -is otherwise applied in addition to ignore files (e.g., .gitignore or -\&.ignore). -Multiple glob flags may be used. -Globbing rules match .gitignore globs. -Precede a glob with a \[aq]!\[aq] to exclude it. -.RS -.PP -The \-\-glob flag subsumes the functionality of both the \-\-include and -\-\-exclude flags commonly found in other tools. -.PP -Values given to \-g must be quoted or your shell will expand them and -result in unexpected behavior. -.PP -Combine with the \-\-files flag to return matched filenames (i.e., to -replicate ack/ag\[aq]s \-g flag). -For example: -.IP -.nf -\f[C] -rg\ \-g\ \[aq]*.foo\[aq]\ \-\-files -\f[] -.fi -.RE -.TP -.B \-h, \-\-help -Show this usage message. -.RS -.RE -.TP -.B \-i, \-\-ignore\-case -Case insensitive search. -Overridden by \-\-case\-sensitive. -.RS -.RE -.TP -.B \-n, \-\-line\-number -Show line numbers (1\-based). -This is enabled by default at a tty. -.RS -.RE -.TP -.B \-N, \-\-no\-line\-number -Suppress line numbers. -.RS -.RE -.TP -.B \-q, \-\-quiet -Do not print anything to stdout. -If a match is found in a file, stop searching that file. -.RS -.RE -.TP -.B \-t, \-\-type \f[I]TYPE\f[] ... -Only search files matching TYPE. -Multiple type flags may be provided. -Use the \-\-type\-list flag to list all available types. -.RS -.RE -.TP -.B \-T, \-\-type\-not \f[I]TYPE\f[] ... -Do not search files matching TYPE. -Multiple not\-type flags may be provided. -.RS -.RE -.TP -.B \-u, \-\-unrestricted ... -Reduce the level of \[aq]smart\[aq] searching. -A single \-u doesn\[aq]t respect .gitignore (etc.) files. -Two \-u flags will search hidden files and directories. -Three \-u flags will search binary files. -\-uu is equivalent to \f[C]grep\ \-r\f[], and \-uuu is equivalent to -\f[C]grep\ \-a\ \-r\f[]. -.RS -.PP -Note that the \-u flags are convenient aliases for other combinations of -flags. -\-u aliases \-\-no\-ignore. -\-uu aliases \-\-no\-ignore \-\-hidden. -\-uuu aliases \-\-no\-ignore \-\-hidden \-\-text. -.RE -.TP -.B \-v, \-\-invert\-match -Invert matching. -.RS -.RE -.TP -.B \-w, \-\-word\-regexp -Only show matches surrounded by word boundaries. -This is equivalent to putting \\b before and after the search pattern. -.RS -.RE -.TP -.B \-x, \-\-line\-regexp -Only show matches surrounded by line boundaries. -This is equivalent to putting ^...$ around the search pattern. -.RS -.RE -.TP -.B \-z, \-\-search\-zip -Search in compressed files. -Currently gz, bz2, xz and lzma formats are supported. -.RS -.PP -Note that ripgrep expects to find the decompression binaries for the -respective formats in your system\[aq]s PATH for use with this flag. -.RE -.SH LESS COMMON OPTIONS -.TP -.B \-A, \-\-after\-context \f[I]NUM\f[] -Show NUM lines after each match. -.RS -.RE -.TP -.B \-B, \-\-before\-context \f[I]NUM\f[] -Show NUM lines before each match. -.RS -.RE -.TP -.B \-C, \-\-context \f[I]NUM\f[] -Show NUM lines before and after each match. -.RS -.RE -.TP -.B \-\-colors \f[I]SPEC\f[] ... -This flag specifies color settings for use in the output. -This flag may be provided multiple times. -Settings are applied iteratively. -Colors are limited to one of eight choices: red, blue, green, cyan, -magenta, yellow, white and black. -Styles are limited to nobold, bold, nointense or intense. -.RS -.PP -The format of the flag is {type}:{attribute}:{value}. -{type} should be one of path, line, column or match. -{attribute} can be fg, bg or style. -Value is either a color (for fg and bg) or a text style. -A special format, {type}:none, will clear all color settings for {type}. -.PP -For example, the following command will change the match color to -magenta and the background color for line numbers to yellow: -.IP -.nf -\f[C] -rg\ \-\-colors\ \[aq]match:fg:magenta\[aq]\ \-\-colors\ \[aq]line:bg:yellow\[aq]\ foo. -\f[] -.fi -.RE -.TP -.B \-\-column -Show column numbers (1 based) in output. -This only shows the column numbers for the first match on each line. -Note that this doesn\[aq]t try to account for Unicode. -One byte is equal to one column. -This implies \-\-line\-number. -.RS -.RE -.TP -.B \-\-context\-separator \f[I]SEPARATOR\f[] -The string to use when separating non\-continuous context lines. -Escape sequences may be used. -[default: \-\-] -.RS -.RE -.TP -.B \-\-debug -Show debug messages. -.RS -.RE -.TP -.B \-E, \-\-encoding \f[I]ENCODING\f[] -Specify the text encoding that ripgrep will use on all files searched. -The default value is \[aq]auto\[aq], which will cause ripgrep to do a -best effort automatic detection of encoding on a per\-file basis. -Other supported values can be found in the list of labels here: -https://encoding.spec.whatwg.org/#concept\-encoding\-get -.RS -.RE -.TP -.B \-f, \-\-file \f[I]FILE\f[] ... -Search for patterns from the given file, with one pattern per line. -When this flag is used or multiple times or in combination with the -\-e/\-\-regexp flag, then all patterns provided are searched. -Empty pattern lines will match all input lines, and the newline is not -counted as part of the pattern. -.RS -.RE -.TP -.B \-\-files -Print each file that would be searched (but don\[aq]t search). -.RS -.PP -Combine with the \-g flag to return matched paths, for example: -.IP -.nf -\f[C] -rg\ \-g\ \[aq]*.foo\[aq]\ \-\-files -\f[] -.fi -.RE -.TP -.B \-l, \-\-files\-with\-matches -Only show path of each file with matches. -.RS -.RE -.TP -.B \-\-files\-without\-match -Only show path of each file with no matches. -.RS -.RE -.TP -.B \-H, \-\-with\-filename -Display the file name for matches. -This is the default when more than one file is searched. -If \-\-heading is enabled, the file name will be shown above clusters of -matches from each file; otherwise, the file name will be shown on each -match. -.RS -.RE -.TP -.B \-\-no\-filename -Never show the filename for a match. -This is the default when one file is searched. -.RS -.RE -.TP -.B \-\-heading -Show the file name above clusters of matches from each file instead of -showing the file name for every match. -This is the default mode at a tty. -.RS -.RE -.TP -.B \-\-no\-heading -Don\[aq]t group matches by each file. -If \-H/\-\-with\-filename is enabled, then file names will be shown for -every line matched. -This is the default mode when not at a tty. -.RS -.RE -.TP -.B \-\-hidden -Search hidden directories and files. -(Hidden directories and files are skipped by default.) -.RS -.RE -.TP -.B \-\-iglob \f[I]GLOB\f[] ... -Include or exclude files/directories case insensitively. -This always overrides any other ignore logic if there is a conflict, but -is otherwise applied in addition to ignore files (e.g., .gitignore or -\&.ignore). -Multiple glob flags may be used. -Globbing rules match .gitignore globs. -Precede a glob with a \[aq]!\[aq] to exclude it. -.RS -.RE -.TP -.B \-\-ignore\-file \f[I]FILE\f[] ... -Specify additional ignore files for filtering file paths. -Ignore files should be in the gitignore format and are matched relative -to the current working directory. -These ignore files have lower precedence than all other ignore files. -When specifying multiple ignore files, earlier files have lower -precedence than later files. -.RS -.RE -.TP -.B \-L, \-\-follow -Follow symlinks. -.RS -.RE -.TP -.B \-\-line\-number\-width \f[I]NUM\f[] -Specify a width for the displayed line number. -If number of digits in the line number is less than this number, it is -left padded with spaces. -Note: This setting has no effect if \-\-no\-line\-number is enabled. -.RS -.RE -.TP -.B \-M, \-\-max\-columns \f[I]NUM\f[] -Don\[aq]t print lines longer than this limit in bytes. -Longer lines are omitted, and only the number of matches in that line is -printed. -.RS -.RE -.TP -.B \-m, \-\-max\-count \f[I]NUM\f[] -Limit the number of matching lines per file searched to NUM. -.RS -.RE -.TP -.B \-\-max\-filesize \f[I]NUM\f[]+\f[I]SUFFIX\f[]? -Ignore files larger than \f[I]NUM\f[] in size. -Directories will never be ignored. -.RS -.PP -\f[I]SUFFIX\f[] is optional and may be one of K, M or G. -These correspond to kilobytes, megabytes and gigabytes respectively. -If omitted the input is treated as bytes. -.RE -.TP -.B \-\-maxdepth \f[I]NUM\f[] -Descend at most NUM directories below the command line arguments. -A value of zero searches only the starting\-points themselves. -.RS -.RE -.TP -.B \-\-mmap -Search using memory maps when possible. -This is enabled by default when ripgrep thinks it will be faster. -(Note that mmap searching doesn\[aq]t currently support the various -context related options.) -.RS -.RE -.TP -.B \-\-no\-config -Never read configuration files. -When this flag is present, ripgrep will not respect the -RIPGREP_CONFIG_PATH environment variable. -.RS -.PP -If ripgrep ever grows a feature to automatically read configuration -files in pre\-defined locations, then this flag will also disable that -behavior as well. -.RE -.TP -.B \-\-no\-messages -Suppress all error messages. -.RS -.RE -.TP -.B \-\-no\-mmap -Never use memory maps, even when they might be faster. -.RS -.RE -.TP -.B \-\-no\-ignore -Don\[aq]t respect ignore files (.gitignore, .ignore, etc.) This implies -\-\-no\-ignore\-parent. -.RS -.RE -.TP -.B \-\-no\-ignore\-parent -Don\[aq]t respect ignore files in parent directories. -.RS -.RE -.TP -.B \-\-no\-ignore\-vcs -Don\[aq]t respect version control ignore files (e.g., .gitignore). -Note that .ignore files will continue to be respected. -.RS -.RE -.TP -.B \-0, \-\-null -Whenever a file name is printed, follow it with a NUL byte. -This includes printing filenames before matches, and when printing a -list of matching files such as with \-\-count, \-\-files\-with\-matches -and \-\-files. -.RS -.RE -.TP -.B \-o, \-\-only\-matching -Print only the matched (non\-empty) parts of a matching line, with each -such part on a separate output line. -.RS -.RE -.TP -.B \-\-passthru, \-\-passthrough -Show both matching and non\-matching lines. -This option cannot be used with \-\-only\-matching or \-\-replace. -.RS -.RE -.TP -.B \-\-path\-separator \f[I]SEPARATOR\f[] -The path separator to use when printing file paths. -This defaults to your platform\[aq]s path separator, which is / on Unix -and \\ on Windows. -This flag is intended for overriding the default when the environment -demands it (e.g., cygwin). -A path separator is limited to a single byte. -.RS -.RE -.TP -.B \-p, \-\-pretty -Alias for \-\-color=always \-\-heading \-\-line\-number. -.RS -.RE -.TP -.B \-r, \-\-replace \f[I]ARG\f[] -Replace every match with the string given when printing search results. -Neither this flag nor any other flag will modify your files. -.RS -.PP -Capture group indices (e.g., $5) and names (e.g., $foo) are supported in -the replacement string. -.PP -Note that the replacement by default replaces each match, and NOT the -entire line. -To replace the entire line, you should match the entire line. -For example, to emit only the first phone numbers in each line: -.IP -.nf -\f[C] -rg\ \[aq]^.*([0\-9]{3}\-[0\-9]{3}\-[0\-9]{4}).*$\[aq]\ \-\-replace\ \[aq]$1\[aq] -\f[] -.fi -.RE -.TP -.B \-s, \-\-case\-sensitive -Search case sensitively (default). -Overrides \-\-ignore\-case and \-\-smart\-case. -.RS -.RE -.TP -.B \-S, \-\-smart\-case -Search case insensitively if the pattern is all lowercase. -Search case sensitively otherwise. -This is overridden by either \-\-case\-sensitive or \-\-ignore\-case. -Note: This feature is smart enough to treat simple classes like \\S as -lowercase, but may not handle more complex syntax like \\p{Ll} as -expected. -.RS -.RE -.TP -.B \-\-sort\-files -Sort results by file path. -Note that this currently disables all parallelism and runs search in a -single thread. -.RS -.RE -.TP -.B \-j, \-\-threads \f[I]ARG\f[] -The number of threads to use. -0 means use the number of logical CPUs (capped at 12). -[default: 0] -.RS -.RE -.TP -.B \-\-version -Show the version number of ripgrep and exit. -.RS -.RE -.TP -.B \-\-vimgrep -Show results with every match on its own line, including line numbers -and column numbers. -With this option, a line with more than one match will be printed more -than once. -.RS -.PP -Recommended .vimrc configuration: -.IP -.nf -\f[C] -\ \ set\ grepprg=rg\\\ \-\-vimgrep -\ \ set\ grepformat^=%f:%l:%c:%m -\f[] -.fi -.PP -Use :grep to grep for something, then :cn and :cp to navigate through -the matches. -.RE -.SH FILE TYPE MANAGEMENT OPTIONS -.TP -.B \-\-type\-list -Show all supported file types and their associated globs. -.RS -.RE -.TP -.B \-\-type\-add \f[I]ARG\f[] ... -Add a new glob for a particular file type. -Only one glob can be added at a time. -Multiple \-\-type\-add flags can be provided. -Unless \-\-type\-clear is used, globs are added to any existing globs -inside of ripgrep. -Note that this must be passed to every invocation of rg. -Type settings are NOT persisted. -Example: -.RS -.IP -.nf -\f[C] -\ \ rg\ \-\-type\-add\ \[aq]foo:*.foo\[aq]\ \-tfoo\ PATTERN -\f[] -.fi -.PP -\-\-type\-add can also be used to include rules from other types with -the special include directive. -The include directive permits specifying one or more other type names -(separated by a comma) that have been defined and its rules will -automatically be imported into the type specified. -For example, to create a type called src that matches C++, Python and -Markdown files, one can use: -.IP -.nf -\f[C] -\ \ \-\-type\-add\ \[aq]src:include:cpp,py,md\[aq] -\f[] -.fi -.PP -Additional glob rules can still be added to the src type by using the -\-\-type\-add flag again: -.IP -.nf -\f[C] -\ \ \-\-type\-add\ \[aq]src:include:cpp,py,md\[aq]\ \-\-type\-add\ \[aq]src:*.foo\[aq] -\f[] -.fi -.PP -Note that type names must consist only of Unicode letters or numbers. -Punctuation characters are not allowed. -.RE -.TP -.B \-\-type\-clear \f[I]TYPE\f[] ... -Clear the file type globs previously defined for TYPE. -This only clears the default type definitions that are found inside of -ripgrep. -Note that this must be passed to every invocation of rg. -.RS -.RE -.SH CONFIGURATION FILES -.PP -ripgrep supports reading configuration files that change ripgrep\[aq]s -default behavior. -The format of the configuration file is an "rc" style and is very -simple. -It is defined by two rules: -.IP -.nf -\f[C] -1.\ Every\ line\ is\ a\ shell\ argument,\ after\ trimming\ ASCII\ whitespace. -2.\ Lines\ starting\ with\ \[aq]#\[aq]\ (optionally\ preceded\ by\ any\ amount\ of -\ \ \ ASCII\ whitespace)\ are\ ignored. -\f[] -.fi -.PP -ripgrep will look for a single configuration file if and only if the -RIPGREP_CONFIG_PATH environment variable is set and is non\-empty. -ripgrep will parse shell arguments from this file on startup and will -behave as if the arguments in this file were prepended to any explicit -arguments given to ripgrep on the command line. -.PP -For example, if your ripgreprc file contained a single line: -.IP -.nf -\f[C] -\-\-smart\-case -\f[] -.fi -.PP -then the following command -.IP -.nf -\f[C] -RIPGREP_CONFIG_PATH=wherever/.ripgreprc\ rg\ foo -\f[] -.fi -.PP -would behave identically to the following command -.IP -.nf -\f[C] -rg\ \-\-smart\-case\ foo -\f[] -.fi -.PP -ripgrep also provides a flag, \-\-no\-config, that when present will -suppress any and all support for configuration. -This includes any future support for auto\-loading configuration files -from pre\-determined paths. -.PP -Conflicts between configuration files and explicit arguments are handled -exactly like conflicts in the same command line invocation. -That is, this command: -.IP -.nf -\f[C] -RIPGREP_CONFIG_PATH=wherever/.ripgreprc\ rg\ foo\ \-\-case\-sensitive -\f[] -.fi -.PP -is exactly equivalent to -.IP -.nf -\f[C] -rg\ \-\-smart\-case\ foo\ \-\-case\-sensitive -\f[] -.fi -.PP -in which case, the \-\-case\-sensitive flag would override the -\-\-smart\-case flag. -.SH SHELL COMPLETION -.PP -Shell completion files are included in the release tarball for Bash, -Fish, Zsh and PowerShell. -.PP -For \f[B]bash\f[], move \f[C]rg.bash\-completion\f[] to -\f[C]$XDG_CONFIG_HOME/bash_completion\f[] or -\f[C]/etc/bash_completion.d/\f[]. -.PP -For \f[B]fish\f[], move \f[C]rg.fish\f[] to -\f[C]$HOME/.config/fish/completions\f[]. diff --git a/doc/rg.1.md b/doc/rg.1.md deleted file mode 100644 index c92c6aa3a..000000000 --- a/doc/rg.1.md +++ /dev/null @@ -1,456 +0,0 @@ -# NAME - -rg - recursively search current directory for lines matching a pattern - -# SYNOPSIS - -rg [*OPTIONS*] *PATTERN* [*PATH* ...] - -rg [*OPTIONS*] [-e *PATTERN* ...] [-f *FILE* ...] [*PATH* ...] - -rg [*OPTIONS*] --files [*PATH* ...] - -rg [*OPTIONS*] --type-list - -rg [*OPTIONS*] --help - -rg [*OPTIONS*] --version - -# DESCRIPTION - -ripgrep (rg) combines the usability of The Silver Searcher (an ack clone) with -the raw speed of grep. - -ripgrep's regex engine uses finite automata and guarantees linear time -searching. Because of this, features like backreferences and arbitrary -lookaround are not supported. - -Note that ripgrep may abort unexpectedly when using default settings if it -searches a file that is simultaneously truncated. This behavior can be avoided -by passing the --no-mmap flag. - -Project home page: https://github.com/BurntSushi/ripgrep - -# POSITIONAL ARGUMENTS - -*PATTERN* -: A regular expression used for searching. To match a pattern beginning with a - dash, use the -e/--regexp option. - -*PATH* -: A file or directory to search. Directories are searched recursively. Paths - specified expicitly on the command line override glob and ignore rules. - -# COMMON OPTIONS - --a, --text -: Search binary files as if they were text. - --c, --count -: Only show count of line matches for each file. - ---color *WHEN* -: Whether to use color in the output. Valid values are never, auto, always or - ansi. The default is auto. When always is used, coloring is attempted based - on your environment. When ansi is used, coloring is forcefully done using - ANSI escape color codes. - --e, --regexp *PATTERN* ... -: Use PATTERN to search. This option can be provided multiple times, where all - patterns given are searched. This is also useful when searching for patterns - that start with a dash. - --F, --fixed-strings -: Treat the pattern as a literal string instead of a regular expression. - --g, --glob *GLOB* ... -: Include or exclude files for searching that match the given glob. This always - overrides any other ignore logic if there is a conflict, but is otherwise - applied in addition to ignore files (e.g., .gitignore or .ignore). Multiple - glob flags may be used. Globbing rules match .gitignore globs. Precede a - glob with a '!' to exclude it. - - The --glob flag subsumes the functionality of both the --include and - --exclude flags commonly found in other tools. - - Values given to -g must be quoted or your shell will expand them and result - in unexpected behavior. - - Combine with the --files flag to return matched filenames - (i.e., to replicate ack/ag's -g flag). For example: - - rg -g '*.foo' --files - --h, --help -: Show this usage message. - --i, --ignore-case -: Case insensitive search. Overridden by --case-sensitive. - --n, --line-number -: Show line numbers (1-based). This is enabled by default at a tty. - --N, --no-line-number -: Suppress line numbers. - --q, --quiet -: Do not print anything to stdout. If a match is found in a file, stop - searching that file. - --t, --type *TYPE* ... -: Only search files matching TYPE. Multiple type flags may be provided. Use the - --type-list flag to list all available types. - --T, --type-not *TYPE* ... -: Do not search files matching TYPE. Multiple not-type flags may be provided. - --u, --unrestricted ... -: Reduce the level of 'smart' searching. A single -u doesn't respect .gitignore - (etc.) files. Two -u flags will search hidden files and directories. Three - -u flags will search binary files. -uu is equivalent to `grep -r`, and -uuu - is equivalent to `grep -a -r`. - - Note that the -u flags are convenient aliases for other combinations of - flags. -u aliases --no-ignore. -uu aliases --no-ignore --hidden. - -uuu aliases --no-ignore --hidden --text. - --v, --invert-match -: Invert matching. - --w, --word-regexp -: Only show matches surrounded by word boundaries. This is equivalent to - putting \\b before and after the search pattern. - --x, --line-regexp -: Only show matches surrounded by line boundaries. This is equivalent to - putting ^...$ around the search pattern. - --z, --search-zip -: Search in compressed files. Currently gz, bz2, xz and lzma - formats are supported. - - Note that ripgrep expects to find the decompression binaries for the - respective formats in your system's PATH for use with this flag. - -# LESS COMMON OPTIONS - --A, --after-context *NUM* -: Show NUM lines after each match. - --B, --before-context *NUM* -: Show NUM lines before each match. - --C, --context *NUM* -: Show NUM lines before and after each match. - ---colors *SPEC* ... -: This flag specifies color settings for use in the output. This flag may be - provided multiple times. Settings are applied iteratively. Colors are limited - to one of eight choices: red, blue, green, cyan, magenta, yellow, white and - black. Styles are limited to nobold, bold, nointense or intense. - - The format of the flag is {type}:{attribute}:{value}. {type} should be one - of path, line, column or match. {attribute} can be fg, bg or style. Value - is either a color (for fg and bg) or a text style. A special format, - {type}:none, will clear all color settings for {type}. - - For example, the following command will change the match color to magenta - and the background color for line numbers to yellow: - - rg --colors 'match:fg:magenta' --colors 'line:bg:yellow' foo. - ---column -: Show column numbers (1 based) in output. This only shows the column - numbers for the first match on each line. Note that this doesn't try - to account for Unicode. One byte is equal to one column. This implies - --line-number. - ---context-separator *SEPARATOR* -: The string to use when separating non-continuous context lines. Escape - sequences may be used. [default: --] - ---debug -: Show debug messages. - --E, --encoding *ENCODING* -: Specify the text encoding that ripgrep will use on all files - searched. The default value is 'auto', which will cause ripgrep to do - a best effort automatic detection of encoding on a per-file basis. - Other supported values can be found in the list of labels here: - https://encoding.spec.whatwg.org/#concept-encoding-get - --f, --file *FILE* ... -: Search for patterns from the given file, with one pattern per line. When this - flag is used or multiple times or in combination with the -e/--regexp flag, - then all patterns provided are searched. Empty pattern lines will match all - input lines, and the newline is not counted as part of the pattern. - ---files -: Print each file that would be searched (but don't search). - - Combine with the -g flag to return matched paths, for example: - - rg -g '*.foo' --files - --l, --files-with-matches -: Only show path of each file with matches. - ---files-without-match -: Only show path of each file with no matches. - --H, --with-filename -: Display the file name for matches. This is the default when - more than one file is searched. If --heading is enabled, the - file name will be shown above clusters of matches from each - file; otherwise, the file name will be shown on each match. - ---no-filename -: Never show the filename for a match. This is the default when - one file is searched. - ---heading -: Show the file name above clusters of matches from each file instead of - showing the file name for every match. This is the default mode at a tty. - ---no-heading -: Don't group matches by each file. If -H/--with-filename is enabled, then - file names will be shown for every line matched. This is the default mode - when not at a tty. - ---hidden -: Search hidden directories and files. (Hidden directories and files are - skipped by default.) - ---iglob *GLOB* ... -: Include or exclude files/directories case insensitively. This always - overrides any other ignore logic if there is a conflict, but is otherwise - applied in addition to ignore files (e.g., .gitignore or .ignore). Multiple - glob flags may be used. Globbing rules match .gitignore globs. Precede a - glob with a '!' to exclude it. - ---ignore-file *FILE* ... -: Specify additional ignore files for filtering file paths. - Ignore files should be in the gitignore format and are matched - relative to the current working directory. These ignore files - have lower precedence than all other ignore files. When - specifying multiple ignore files, earlier files have lower - precedence than later files. - --L, --follow -: Follow symlinks. - ---line-number-width *NUM* -: Specify a width for the displayed line number. If number of digits - in the line number is less than this number, it is left padded with - spaces. Note: This setting has no effect if --no-line-number is - enabled. - --M, --max-columns *NUM* -: Don't print lines longer than this limit in bytes. Longer lines are omitted, - and only the number of matches in that line is printed. - --m, --max-count *NUM* -: Limit the number of matching lines per file searched to NUM. - ---max-filesize *NUM*+*SUFFIX*? -: Ignore files larger than *NUM* in size. Directories will never be ignored. - - *SUFFIX* is optional and may be one of K, M or G. These correspond to - kilobytes, megabytes and gigabytes respectively. If omitted the input is - treated as bytes. - ---maxdepth *NUM* -: Descend at most NUM directories below the command line arguments. - A value of zero searches only the starting-points themselves. - ---mmap -: Search using memory maps when possible. This is enabled by default - when ripgrep thinks it will be faster. (Note that mmap searching - doesn't currently support the various context related options.) - ---no-config -: Never read configuration files. When this flag is present, ripgrep will not - respect the RIPGREP_CONFIG_PATH environment variable. - - If ripgrep ever grows a feature to automatically read configuration files - in pre-defined locations, then this flag will also disable that behavior as - well. - ---no-messages -: Suppress all error messages. - ---no-mmap -: Never use memory maps, even when they might be faster. - ---no-ignore -: Don't respect ignore files (.gitignore, .ignore, etc.) - This implies --no-ignore-parent. - ---no-ignore-parent -: Don't respect ignore files in parent directories. - ---no-ignore-vcs -: Don't respect version control ignore files (e.g., .gitignore). - Note that .ignore files will continue to be respected. - --0, --null -: Whenever a file name is printed, follow it with a NUL byte. - This includes printing filenames before matches, and when printing - a list of matching files such as with --count, --files-with-matches - and --files. - --o, --only-matching -: Print only the matched (non-empty) parts of a matching line, with each such - part on a separate output line. - ---passthru, --passthrough -: Show both matching and non-matching lines. This option cannot be used with - --only-matching or --replace. - ---path-separator *SEPARATOR* -: The path separator to use when printing file paths. This defaults to your - platform's path separator, which is / on Unix and \\ on Windows. This flag is - intended for overriding the default when the environment demands it (e.g., - cygwin). A path separator is limited to a single byte. - --p, --pretty -: Alias for --color=always --heading --line-number. - --r, --replace *ARG* -: Replace every match with the string given when printing search results. - Neither this flag nor any other flag will modify your files. - - Capture group indices (e.g., $5) and names (e.g., $foo) are supported - in the replacement string. - - Note that the replacement by default replaces each match, and NOT the - entire line. To replace the entire line, you should match the entire line. - For example, to emit only the first phone numbers in each line: - - rg '^.*([0-9]{3}-[0-9]{3}-[0-9]{4}).*$' --replace '$1' - --s, --case-sensitive -: Search case sensitively (default). Overrides --ignore-case and --smart-case. - --S, --smart-case -: Search case insensitively if the pattern is all lowercase. - Search case sensitively otherwise. This is overridden by either - --case-sensitive or --ignore-case. Note: This feature is smart enough - to treat simple classes like \\S as lowercase, but may not handle more - complex syntax like \\p{Ll} as expected. - ---sort-files -: Sort results by file path. Note that this currently - disables all parallelism and runs search in a single thread. - --j, --threads *ARG* -: The number of threads to use. 0 means use the number of logical CPUs - (capped at 12). [default: 0] - ---version -: Show the version number of ripgrep and exit. - ---vimgrep -: Show results with every match on its own line, including - line numbers and column numbers. With this option, a line with - more than one match will be printed more than once. - - Recommended .vimrc configuration: - - set grepprg=rg\ --vimgrep - set grepformat^=%f:%l:%c:%m - - Use :grep to grep for something, then :cn and :cp to navigate through the - matches. - -# FILE TYPE MANAGEMENT OPTIONS - ---type-list -: Show all supported file types and their associated globs. - ---type-add *ARG* ... -: Add a new glob for a particular file type. Only one glob can be added - at a time. Multiple --type-add flags can be provided. Unless --type-clear - is used, globs are added to any existing globs inside of ripgrep. Note that - this must be passed to every invocation of rg. Type settings are NOT - persisted. Example: - - rg --type-add 'foo:*.foo' -tfoo PATTERN - - --type-add can also be used to include rules from other types - with the special include directive. The include directive - permits specifying one or more other type names (separated by a - comma) that have been defined and its rules will automatically - be imported into the type specified. For example, to create a - type called src that matches C++, Python and Markdown files, one - can use: - - --type-add 'src:include:cpp,py,md' - - Additional glob rules can still be added to the src type by - using the --type-add flag again: - - --type-add 'src:include:cpp,py,md' --type-add 'src:*.foo' - - Note that type names must consist only of Unicode letters or - numbers. Punctuation characters are not allowed. - ---type-clear *TYPE* ... -: Clear the file type globs previously defined for TYPE. This only clears - the default type definitions that are found inside of ripgrep. Note - that this must be passed to every invocation of rg. - -# CONFIGURATION FILES - -ripgrep supports reading configuration files that change -ripgrep's default behavior. The format of the configuration file is an -"rc" style and is very simple. It is defined by two rules: - - 1. Every line is a shell argument, after trimming ASCII whitespace. - 2. Lines starting with '#' (optionally preceded by any amount of - ASCII whitespace) are ignored. - -ripgrep will look for a single configuration file if and only if the -RIPGREP_CONFIG_PATH environment variable is set and is non-empty. -ripgrep will parse shell arguments from this file on startup and will -behave as if the arguments in this file were prepended to any explicit -arguments given to ripgrep on the command line. - -For example, if your ripgreprc file contained a single line: - - --smart-case - -then the following command - - RIPGREP_CONFIG_PATH=wherever/.ripgreprc rg foo - -would behave identically to the following command - - rg --smart-case foo - -ripgrep also provides a flag, --no-config, that when present will suppress -any and all support for configuration. This includes any future support -for auto-loading configuration files from pre-determined paths. - -Conflicts between configuration files and explicit arguments are handled -exactly like conflicts in the same command line invocation. That is, -this command: - - RIPGREP_CONFIG_PATH=wherever/.ripgreprc rg foo --case-sensitive - -is exactly equivalent to - - rg --smart-case foo --case-sensitive - -in which case, the --case-sensitive flag would override the --smart-case -flag. - -# SHELL COMPLETION - -Shell completion files are included in the release tarball for Bash, Fish, Zsh -and PowerShell. - -For **bash**, move `rg.bash-completion` to `$XDG_CONFIG_HOME/bash_completion` -or `/etc/bash_completion.d/`. - -For **fish**, move `rg.fish` to `$HOME/.config/fish/completions`. diff --git a/doc/rg.1.txt.tpl b/doc/rg.1.txt.tpl new file mode 100644 index 000000000..a1068c09b --- /dev/null +++ b/doc/rg.1.txt.tpl @@ -0,0 +1,136 @@ +rg(1) +===== + +Name +---- +rg - recursively search current directory for lines matching a pattern + + +Synopsis +-------- +*rg* [_OPTIONS_] _PATTERN_ [_PATH_...] + +*rg* [_OPTIONS_] [*-e* _PATTERN_...] [*-f* _PATH_...] [_PATH_...] + +*rg* [_OPTIONS_] *--files* [_PATH_...] + +*rg* [_OPTIONS_] *--type-list* + +*rg* [_OPTIONS_] *--help* + +*rg* [_OPTIONS_] *--version* + + +DESCRIPTION +----------- +ripgrep (rg) recursively searches your current directory for a regex pattern. +By default, ripgrep will respect your `.gitignore` and automatically skip +hidden files/directories and binary files. + +ripgrep's regex engine uses finite automata and guarantees linear time +searching. Because of this, features like backreferences and arbitrary +lookaround are not supported. + + +POSITIONAL ARGUMENTS +-------------------- +_PATTERN_:: + A regular expression used for searching. To match a pattern beginning with a + dash, use the -e/--regexp option. + +_PATH_:: + A file or directory to search. Directories are searched recursively. Paths + specified expicitly on the command line override glob and ignore rules. + + +OPTIONS +------- +{OPTIONS} + + +EXIT STATUS +----------- +If ripgrep finds a match, then the exit status of the program is 0. If no match +could be found, then the exit status is non-zero. + + +CONFIGURATION FILES +------------------- +ripgrep supports reading configuration files that change ripgrep's default +behavior. The format of the configuration file is an "rc" style and is very +simple. It is defined by two rules: + + 1. Every line is a shell argument, after trimming ASCII whitespace. + 2. Lines starting with _#_ (optionally preceded by any amount of + ASCII whitespace) are ignored. + +ripgrep will look for a single configuration file if and only if the +_RIPGREP_CONFIG_PATH_ environment variable is set and is non-empty. +ripgrep will parse shell arguments from this file on startup and will +behave as if the arguments in this file were prepended to any explicit +arguments given to ripgrep on the command line. + +For example, if your ripgreprc file contained a single line: + + --smart-case + +then the following command + + RIPGREP_CONFIG_PATH=wherever/.ripgreprc rg foo + +would behave identically to the following command + + rg --smart-case foo + +ripgrep also provides a flag, *--no-config*, that when present will suppress +any and all support for configuration. This includes any future support +for auto-loading configuration files from pre-determined paths. + +Conflicts between configuration files and explicit arguments are handled +exactly like conflicts in the same command line invocation. That is, +this command: + + RIPGREP_CONFIG_PATH=wherever/.ripgreprc rg foo --case-sensitive + +is exactly equivalent to + + rg --smart-case foo --case-sensitive + +in which case, the *--case-sensitive* flag would override the *--smart-case* +flag. + + +SHELL COMPLETION +---------------- +Shell completion files are included in the release tarball for Bash, Fish, Zsh +and PowerShell. + +For *bash*, move `rg.bash-completion` to `$XDG_CONFIG_HOME/bash_completion` +or `/etc/bash_completion.d/`. + +For *fish*, move `rg.fish` to `$HOME/.config/fish/completions`. + + +CAVEATS +------- +ripgrep may abort unexpectedly when using default settings if it searches a +file that is simultaneously truncated. This behavior can be avoided by passing +the --no-mmap flag which will forcefully disable the use of memory maps in all +cases. + + +VERSION +------- +{VERSION} + + +HOMEPAGE +-------- +https://github.com/BurntSushi/ripgrep + +Please report bugs and feature requests in the issue tracker. + + +AUTHORS +------- +Andrew Gallant diff --git a/src/app.rs b/src/app.rs index 3591dc222..c05fd01bc 100644 --- a/src/app.rs +++ b/src/app.rs @@ -57,7 +57,7 @@ pub fn app() -> App<'static, 'static> { // 'static, but we need to build the version string dynamically. We can // fake the 'static lifetime with lazy_static. lazy_static! { - static ref LONG_VERSION: String = long_version(); + static ref LONG_VERSION: String = long_version(None); } let mut app = App::new("ripgrep") @@ -78,7 +78,11 @@ pub fn app() -> App<'static, 'static> { } /// Return the "long" format of ripgrep's version string. -fn long_version() -> String { +/// +/// If a revision hash is given, then it is used. If one isn't given, then +/// the RIPGREP_BUILD_GIT_HASH env var is inspect for it. If that isn't set, +/// then a revision hash is not included in the version string returned. +pub fn long_version(revision_hash: Option<&str>) -> String { // Let's say whether faster CPU instructions are enabled or not. let mut features = vec![]; if cfg!(feature = "simd-accel") { @@ -93,7 +97,7 @@ fn long_version() -> String { } // Do we have a git hash? // (Yes, if ripgrep was built on a machine with `git` installed.) - let hash = match option_env!("RIPGREP_BUILD_GIT_HASH") { + let hash = match revision_hash.or(option_env!("RIPGREP_BUILD_GIT_HASH")) { None => String::new(), Some(githash) => format!(" (rev {})", githash), }; @@ -113,26 +117,26 @@ type Arg = clap::Arg<'static, 'static>; /// use of clap. #[allow(dead_code)] #[derive(Clone)] -struct RGArg { +pub struct RGArg { /// The underlying clap argument. claparg: Arg, /// The name of this argument. This is always present and is the name /// used in the code to find the value of an argument at runtime. - name: &'static str, + pub name: &'static str, /// A short documentation string describing this argument. This string /// should fit on a single line and be a complete sentence. /// /// This is shown in the `-h` output. - doc_short: &'static str, + pub doc_short: &'static str, /// A longer documentation string describing this argument. This usually /// starts with the contents of `doc_short`. This is also usually many /// lines, potentially paragraphs, and may contain examples and additional /// prose. /// /// This is shown in the `--help` output. - doc_long: &'static str, + pub doc_long: &'static str, /// The type of this argument. - kind: RGArgKind, + pub kind: RGArgKind, } /// The kind of a ripgrep argument. @@ -149,7 +153,7 @@ struct RGArg { /// why; the state we do capture is motivated by use cases (like generating /// documentation). #[derive(Clone)] -enum RGArgKind { +pub enum RGArgKind { /// A positional argument. Positional { /// The name of the value used in the `-h/--help` output. By @@ -476,7 +480,8 @@ macro_rules! long { ($lit:expr) => { concat!($lit, " ") } } -fn all_args_and_flags() -> Vec { +/// Generate a sequence of all positional and flag arguments. +pub fn all_args_and_flags() -> Vec { let mut args = vec![]; // The positional arguments must be defined first and in order. arg_pattern(&mut args);