Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ test = [ "uu_test" ]
[workspace]

[dependencies]
clap = "2.33.3"
lazy_static = { version="1.3" }
textwrap = { version="=0.11.0", features=["term_size"] } # !maint: [2020-05-10; rivy] unstable crate using undocumented features; pinned currently, will review
uucore = { version=">=0.0.8", package="uucore", path="src/uucore" }
Expand Down
8 changes: 8 additions & 0 deletions GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -314,13 +314,21 @@ else
endif
$(foreach man, $(filter $(INSTALLEES), $(basename $(notdir $(wildcard $(DOCSDIR)/_build/man/*)))), \
cat $(DOCSDIR)/_build/man/$(man).1 | gzip > $(INSTALLDIR_MAN)/$(PROG_PREFIX)$(man).1.gz &&) :
$(foreach prog, $(INSTALLEES), \
$(BUILDDIR)/coreutils completion $(prog) zsh > $(DESTDIR)$(PREFIX)/share/zsh/site-functions/_$(PROG_PREFIX)$(prog); \
$(BUILDDIR)/coreutils completion $(prog) bash > $(DESTDIR)$(PREFIX)/share/bash-completion/completions/$(PROG_PREFIX)$(prog); \
$(BUILDDIR)/coreutils completion $(prog) fish > $(DESTDIR)$(PREFIX)/share/fish/vendor_completions.d/$(PROG_PREFIX)$(prog).fish; \
)

uninstall:
ifeq (${MULTICALL}, y)
rm -f $(addprefix $(INSTALLDIR_BIN)/,$(PROG_PREFIX)coreutils)
endif
rm -f $(addprefix $(INSTALLDIR_MAN)/,$(PROG_PREFIX)coreutils.1.gz)
rm -f $(addprefix $(INSTALLDIR_BIN)/$(PROG_PREFIX),$(PROGS))
rm -f $(addprefix $(DESTDIR)$(PREFIX)/share/zsh/site-functions/_$(PROG_PREFIX),$(PROGS))
rm -f $(addprefix $(DESTDIR)$(PREFIX)/share/bash-completion/completions/$(PROG_PREFIX),$(PROGS))
rm -f $(addprefix $(DESTDIR)$(PREFIX)/share/fish/vendor_completions.d/$(PROG_PREFIX),$(addsuffix .fish,$(PROGS)))
rm -f $(addprefix $(INSTALLDIR_MAN)/$(PROG_PREFIX),$(addsuffix .1.gz,$(PROGS)))

.PHONY: all build build-coreutils build-pkgs build-docs test distclean clean busytest install uninstall
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ $ cargo install --path .

This command will install uutils into Cargo's *bin* folder (*e.g.* `$HOME/.cargo/bin`).

This does not install files necessary for shell completion. For shell completion to work,
use `GNU Make` or see `Manually install shell completions`.

### GNU Make

To install all available utilities:
Expand Down Expand Up @@ -179,6 +182,10 @@ Set install parent directory (default value is /usr/local):
$ make PREFIX=/my/path install
```

Installing with `make` installs shell completions for all installed utilities
for `bash`, `fish` and `zsh`. Completions for `elvish` and `powershell` can also
be generated; See `Manually install shell completions`.

### NixOS

The [standard package set](https://nixos.org/nixpkgs/manual/) of [NixOS](https://nixos.org/)
Expand All @@ -188,6 +195,23 @@ provides this package out of the box since 18.03:
$ nix-env -iA nixos.uutils-coreutils
```

### Manually install shell completions

The `coreutils` binary can generate completions for the `bash`, `elvish`, `fish`, `powershell`
and `zsh` shells. It prints the result to stdout.

The syntax is:
```bash
cargo run completion <utility> <shell>
```

So, to install completions for `ls` on `bash` to `/usr/local/share/bash-completion/completions/ls`,
run:

```bash
cargo run completion ls bash > /usr/local/share/bash-completion/completions/ls
```

## Un-installation Instructions

Un-installation differs depending on how you have installed uutils. If you used
Expand Down
40 changes: 20 additions & 20 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub fn main() {
let mut tf = File::create(Path::new(&out_dir).join("test_modules.rs")).unwrap();

mf.write_all(
"type UtilityMap<T> = HashMap<&'static str, fn(T) -> i32>;\n\
"type UtilityMap<T> = HashMap<&'static str, (fn(T) -> i32, fn() -> App<'static, 'static>)>;\n\
\n\
fn util_map<T: uucore::Args>() -> UtilityMap<T> {\n\
\tlet mut map = UtilityMap::new();\n\
Expand All @@ -60,8 +60,8 @@ pub fn main() {
mf.write_all(
format!(
"\
\tmap.insert(\"test\", {krate}::uumain);\n\
\t\tmap.insert(\"[\", {krate}::uumain);\n\
\tmap.insert(\"test\", ({krate}::uumain, {krate}::uu_app));\n\
\t\tmap.insert(\"[\", ({krate}::uumain, {krate}::uu_app));\n\
",
krate = krate
)
Expand All @@ -80,7 +80,7 @@ pub fn main() {
k if k.starts_with(override_prefix) => {
mf.write_all(
format!(
"\tmap.insert(\"{k}\", {krate}::uumain);\n",
"\tmap.insert(\"{k}\", ({krate}::uumain, {krate}::uu_app));\n",
k = krate[override_prefix.len()..].to_string(),
krate = krate
)
Expand All @@ -100,7 +100,7 @@ pub fn main() {
"false" | "true" => {
mf.write_all(
format!(
"\tmap.insert(\"{krate}\", r#{krate}::uumain);\n",
"\tmap.insert(\"{krate}\", (r#{krate}::uumain, r#{krate}::uu_app));\n",
krate = krate
)
.as_bytes(),
Expand All @@ -120,20 +120,20 @@ pub fn main() {
mf.write_all(
format!(
"\
\tmap.insert(\"{krate}\", {krate}::uumain);\n\
\t\tmap.insert(\"md5sum\", {krate}::uumain);\n\
\t\tmap.insert(\"sha1sum\", {krate}::uumain);\n\
\t\tmap.insert(\"sha224sum\", {krate}::uumain);\n\
\t\tmap.insert(\"sha256sum\", {krate}::uumain);\n\
\t\tmap.insert(\"sha384sum\", {krate}::uumain);\n\
\t\tmap.insert(\"sha512sum\", {krate}::uumain);\n\
\t\tmap.insert(\"sha3sum\", {krate}::uumain);\n\
\t\tmap.insert(\"sha3-224sum\", {krate}::uumain);\n\
\t\tmap.insert(\"sha3-256sum\", {krate}::uumain);\n\
\t\tmap.insert(\"sha3-384sum\", {krate}::uumain);\n\
\t\tmap.insert(\"sha3-512sum\", {krate}::uumain);\n\
\t\tmap.insert(\"shake128sum\", {krate}::uumain);\n\
\t\tmap.insert(\"shake256sum\", {krate}::uumain);\n\
\tmap.insert(\"{krate}\", ({krate}::uumain, {krate}::uu_app_custom));\n\
\t\tmap.insert(\"md5sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
\t\tmap.insert(\"sha1sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
\t\tmap.insert(\"sha224sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
\t\tmap.insert(\"sha256sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
\t\tmap.insert(\"sha384sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
\t\tmap.insert(\"sha512sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
\t\tmap.insert(\"sha3sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
\t\tmap.insert(\"sha3-224sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
\t\tmap.insert(\"sha3-256sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
\t\tmap.insert(\"sha3-384sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
\t\tmap.insert(\"sha3-512sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
\t\tmap.insert(\"shake128sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
\t\tmap.insert(\"shake256sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
",
krate = krate
)
Expand All @@ -153,7 +153,7 @@ pub fn main() {
_ => {
mf.write_all(
format!(
"\tmap.insert(\"{krate}\", {krate}::uumain);\n",
"\tmap.insert(\"{krate}\", ({krate}::uumain, {krate}::uu_app));\n",
krate = krate
)
.as_bytes(),
Expand Down
52 changes: 49 additions & 3 deletions src/bin/coreutils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

use clap::App;
use clap::Shell;
use std::cmp;
use std::collections::hash_map::HashMap;
use std::ffi::OsString;
Expand Down Expand Up @@ -52,7 +54,7 @@ fn main() {
let binary_as_util = name(&binary);

// binary name equals util name?
if let Some(&uumain) = utils.get(binary_as_util) {
if let Some(&(uumain, _)) = utils.get(binary_as_util) {
process::exit(uumain((vec![binary.into()].into_iter()).chain(args)));
}

Expand All @@ -74,8 +76,12 @@ fn main() {
if let Some(util_os) = util_name {
let util = util_os.as_os_str().to_string_lossy();

if util == "completion" {
gen_completions(args, utils);
}

match utils.get(&util[..]) {
Some(&uumain) => {
Some(&(uumain, _)) => {
process::exit(uumain((vec![util_os].into_iter()).chain(args)));
}
None => {
Expand All @@ -85,7 +91,7 @@ fn main() {
let util = util_os.as_os_str().to_string_lossy();

match utils.get(&util[..]) {
Some(&uumain) => {
Some(&(uumain, _)) => {
let code = uumain(
(vec![util_os, OsString::from("--help")].into_iter())
.chain(args),
Expand Down Expand Up @@ -113,3 +119,43 @@ fn main() {
process::exit(0);
}
}

/// Prints completions for the utility in the first parameter for the shell in the second parameter to stdout
fn gen_completions<T: uucore::Args>(
mut args: impl Iterator<Item = OsString>,
util_map: UtilityMap<T>,
) -> ! {
let utility = args
.next()
.expect("expected utility as the first parameter")
.to_str()
.expect("utility name was not valid utf-8")
.to_owned();
let shell = args
.next()
.expect("expected shell as the second parameter")
.to_str()
.expect("shell name was not valid utf-8")
.to_owned();
let mut app = if utility == "coreutils" {
gen_coreutils_app(util_map)
} else if let Some((_, app)) = util_map.get(utility.as_str()) {
app()
} else {
eprintln!("{} is not a valid utility", utility);
process::exit(1)
};
let shell: Shell = shell.parse().unwrap();
let bin_name = std::env::var("PROG_PREFIX").unwrap_or_default() + &utility;
app.gen_completions_to(bin_name, shell, &mut io::stdout());
io::stdout().flush().unwrap();
process::exit(0);
}

fn gen_coreutils_app<T: uucore::Args>(util_map: UtilityMap<T>) -> App<'static, 'static> {
let mut app = App::new("coreutils");
for (_, (_, sub_app)) in util_map {
app = app.subcommand(sub_app());
}
app
}
13 changes: 8 additions & 5 deletions src/uu/arch/src/arch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@ static ABOUT: &str = "Display machine architecture";
static SUMMARY: &str = "Determine architecture name for current machine.";

pub fn uumain(args: impl uucore::Args) -> i32 {
App::new(executable!())
.version(crate_version!())
.about(ABOUT)
.after_help(SUMMARY)
.get_matches_from(args);
uu_app().get_matches_from(args);

let uts = return_if_err!(1, PlatformInfo::new());
println!("{}", uts.machine().trim());
0
}

pub fn uu_app() -> App<'static, 'static> {
App::new(executable!())
.version(crate_version!())
.about(ABOUT)
.after_help(SUMMARY)
}
5 changes: 5 additions & 0 deletions src/uu/base32/src/base32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ extern crate uucore;

use std::io::{stdin, Read};

use clap::App;
use uucore::encoding::Format;

pub mod base_common;
Expand Down Expand Up @@ -56,3 +57,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {

0
}

pub fn uu_app() -> App<'static, 'static> {
base_common::base_app(executable!(), VERSION, ABOUT)
}
17 changes: 10 additions & 7 deletions src/uu/base32/src/base_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,17 @@ pub fn parse_base_cmd_args(
about: &str,
usage: &str,
) -> Result<Config, String> {
let app = App::new(name)
let app = base_app(name, version, about).usage(usage);
let arg_list = args
.collect_str(InvalidEncodingHandling::ConvertLossy)
.accept_any();
Config::from(app.get_matches_from(arg_list))
}

pub fn base_app<'a>(name: &str, version: &'a str, about: &'a str) -> App<'static, 'a> {
App::new(name)
.version(version)
.about(about)
.usage(usage)
// Format arguments.
.arg(
Arg::with_name(options::DECODE)
Expand All @@ -106,11 +113,7 @@ pub fn parse_base_cmd_args(
)
// "multiple" arguments are used to check whether there is more than one
// file passed in.
.arg(Arg::with_name(options::FILE).index(1).multiple(true));
let arg_list = args
.collect_str(InvalidEncodingHandling::ConvertLossy)
.accept_any();
Config::from(app.get_matches_from(arg_list))
.arg(Arg::with_name(options::FILE).index(1).multiple(true))
}

pub fn get_input<'a>(config: &Config, stdin_ref: &'a Stdin) -> Box<dyn Read + 'a> {
Expand Down
1 change: 1 addition & 0 deletions src/uu/base64/src/base64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
extern crate uucore;

use uu_base32::base_common;
pub use uu_base32::uu_app;

use uucore::encoding::Format;

Expand Down
Loading