diff --git a/.vscode/cspell.dictionaries/workspace.wordlist.txt b/.vscode/cspell.dictionaries/workspace.wordlist.txt index b68da6eb7..e41aba979 100644 --- a/.vscode/cspell.dictionaries/workspace.wordlist.txt +++ b/.vscode/cspell.dictionaries/workspace.wordlist.txt @@ -25,6 +25,7 @@ getrandom globset itertools lscolors +mdbook memchr multifilereader onig @@ -322,6 +323,7 @@ ucommand utmpx uucore uucore_procs +uudoc uumain uutil uutils diff --git a/Cargo.toml b/Cargo.toml index 14265524f..62e5c50af 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ version = "0.0.12" authors = ["uutils developers"] license = "MIT" description = "coreutils ~ GNU coreutils (updated); implemented as universal (cross-platform) utils, written in Rust" +default-run = "coreutils" homepage = "https://github.com/uutils/coreutils" repository = "https://github.com/uutils/coreutils" @@ -389,3 +390,7 @@ unix_socket = "0.5.0" [[bin]] name = "coreutils" path = "src/bin/coreutils.rs" + +[[bin]] +name = "uudoc" +path = "src/bin/uudoc.rs" diff --git a/GNUmakefile b/GNUmakefile index 12cd95013..b43c3596b 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -279,10 +279,7 @@ endif build-coreutils: ${CARGO} build ${CARGOFLAGS} --features "${EXES}" ${PROFILE_CMD} --no-default-features -build-manpages: - cd $(DOCSDIR) && $(MAKE) man - -build: build-coreutils build-pkgs build-manpages +build: build-coreutils build-pkgs $(foreach test,$(filter-out $(SKIP_UTILS),$(PROGS)),$(eval $(call TEST_BUSYBOX,$(test)))) @@ -330,14 +327,11 @@ ifeq (${MULTICALL}, y) cd $(INSTALLDIR_BIN) && $(foreach prog, $(filter-out coreutils, $(INSTALLEES)), \ ln -fs $(PROG_PREFIX)coreutils $(PROG_PREFIX)$(prog) &&) : $(if $(findstring test,$(INSTALLEES)), cd $(INSTALLDIR_BIN) && ln -fs $(PROG_PREFIX)coreutils $(PROG_PREFIX)[) - cat $(DOCSDIR)/_build/man/coreutils.1 | gzip > $(INSTALLDIR_MAN)/$(PROG_PREFIX)coreutils.1.gz else $(foreach prog, $(INSTALLEES), \ $(INSTALL) $(BUILDDIR)/$(prog) $(INSTALLDIR_BIN)/$(PROG_PREFIX)$(prog);) $(if $(findstring test,$(INSTALLEES)), $(INSTALL) $(BUILDDIR)/test $(INSTALLDIR_BIN)/$(PROG_PREFIX)[) 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 &&) : mkdir -p $(DESTDIR)$(PREFIX)/share/zsh/site-functions mkdir -p $(DESTDIR)$(PREFIX)/share/bash-completion/completions mkdir -p $(DESTDIR)$(PREFIX)/share/fish/vendor_completions.d @@ -359,4 +353,4 @@ endif 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 +.PHONY: all build build-coreutils build-pkgs test distclean clean busytest install uninstall diff --git a/README.md b/README.md index 306ca08a7..f9ee6a867 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ have other issues. Rust provides a good, platform-agnostic way of writing systems utilities that are easy to compile anywhere, and this is as good a way as any to try and learn it. + ## Requirements * Rust (`cargo`, `rustc`) @@ -252,6 +253,7 @@ To uninstall from a custom parent directory: # DESTDIR is also supported $ make PREFIX=/my/path uninstall ``` + ## Test Instructions diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 000000000..f2b5c7168 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,3 @@ +book +src/utils +src/SUMMARY.md diff --git a/docs/arch.rst b/docs/arch.rst deleted file mode 100644 index 66b516159..000000000 --- a/docs/arch.rst +++ /dev/null @@ -1,28 +0,0 @@ -.. print machine hardware name - -==== -arch -==== - -.. FIXME: this needs to be autogenerated somehow - --------- -Synopsis --------- - -``arch`` [OPTION]... - ------------ -Description ------------ - -``arch`` is an alias for ``uname -m``. They both print the machine hardware -name. - -An exit code of zero indicates success, whereas anything else means failure. -For this program, a non-zero exit code generally means the user provided -invalid options. - --h, --help print a help menu for this program displaying accepted - options and arguments --v, --version print the version number of this program diff --git a/docs/book.toml b/docs/book.toml new file mode 100644 index 000000000..75982ab31 --- /dev/null +++ b/docs/book.toml @@ -0,0 +1,9 @@ +[book] +authors = ["uutils contributors"] +language = "en" +multilingual = false +src = "src" +title = "uutils Documentation" + +[output.html] +git-repository-url = "https://github.com/rust-lang/cargo/tree/master/src/doc/src" \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst deleted file mode 100644 index 7f782b12a..000000000 --- a/docs/index.rst +++ /dev/null @@ -1,24 +0,0 @@ -.. uutils documentation master file, created by - sphinx-quickstart on Tue Dec 5 23:20:18 2017. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -.. - spell-checker:ignore (directives) genindex maxdepth modindex toctree ; (misc) quickstart - -Welcome to uutils' documentation! -================================= - -.. toctree:: - :maxdepth: 2 - :caption: Contents: - - arch - uutils - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` diff --git a/docs/src/contributing.md b/docs/src/contributing.md new file mode 100644 index 000000000..79ef4d13b --- /dev/null +++ b/docs/src/contributing.md @@ -0,0 +1 @@ +{{ #include ../../CONTRIBUTING.md }} \ No newline at end of file diff --git a/docs/src/index.md b/docs/src/index.md new file mode 100644 index 000000000..3ea5d913a --- /dev/null +++ b/docs/src/index.md @@ -0,0 +1,20 @@ +# uutils Coreutils Documentation + +uutils is an attempt at writing universal (as in cross-platform) CLI +utilities in [Rust](https://www.rust-lang.org). It is available for +Linux, Windows, Mac and other platforms. + +The API reference for `uucore`, the library of functions shared between +various utils, is hosted at at +[docs.rs](https://docs.rs/uucore/latest/uucore/). + +uutils is licensed under the [MIT License](https://github.com/uutils/coreutils/blob/main/LICENSE). + +## Useful links +* [Releases](https://github.com/uutils/coreutils/releases) +* [Source Code](https://github.com/uutils/coreutils) +* [Issues](https://github.com/uutils/coreutils/issues) +* [Discord](https://discord.gg/wQVJbvJ) + +> Note: This manual is automatically generated from the source code and is +> a work in progress. \ No newline at end of file diff --git a/docs/src/installation.md b/docs/src/installation.md new file mode 100644 index 000000000..885b5ecb0 --- /dev/null +++ b/docs/src/installation.md @@ -0,0 +1,3 @@ +# Installation + +{{#include ../../README.md:installation }} \ No newline at end of file diff --git a/docs/src/multicall.md b/docs/src/multicall.md new file mode 100644 index 000000000..5d7b8b169 --- /dev/null +++ b/docs/src/multicall.md @@ -0,0 +1,17 @@ +# Multi-call binary +uutils includes a multi-call binary from which the utils can be invoked. This +reduces the binary size of the binary and can be useful for portability. + +The first argument of the multi-call binary is the util to run, after which +the regular arguments to the util can be passed. + +```shell +coreutils [util] [util options] +``` + +The `--help` flag will print a list of available utils. + +## Example +``` +coreutils ls -l +``` \ No newline at end of file diff --git a/docs/theme/favicon.png b/docs/theme/favicon.png new file mode 100644 index 000000000..1cd1f26ec Binary files /dev/null and b/docs/theme/favicon.png differ diff --git a/docs/theme/head.hbs b/docs/theme/head.hbs new file mode 100644 index 000000000..31cc2dad5 --- /dev/null +++ b/docs/theme/head.hbs @@ -0,0 +1,16 @@ + diff --git a/docs/uutils.rst b/docs/uutils.rst deleted file mode 100644 index e3b8c6a1a..000000000 --- a/docs/uutils.rst +++ /dev/null @@ -1,24 +0,0 @@ -.. run core utilities - -====== -uutils -====== - -.. FIXME: this needs to be autogenerated somehow - --------- -Synopsis --------- - -``uutils`` [OPTION]... [PROGRAM] [OPTION]... [ARGUMENTS]... - ------------ -Description ------------ - -``uutils`` is a program that contains other coreutils commands, somewhat -similar to Busybox. - ---help, -h print a help menu for PROGRAM displaying accepted options and - arguments; if PROGRAM was not given, do the same but for this - program diff --git a/src/bin/uudoc.rs b/src/bin/uudoc.rs new file mode 100644 index 000000000..38e8a0323 --- /dev/null +++ b/src/bin/uudoc.rs @@ -0,0 +1,137 @@ +// This file is part of the uutils coreutils package. +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +use clap::App; +use std::collections::hash_map::HashMap; +use std::ffi::OsString; +use std::fs::File; +use std::io::{self, Write}; + +include!(concat!(env!("OUT_DIR"), "/uutils_map.rs")); + +fn main() -> io::Result<()> { + let utils = util_map::>>(); + match std::fs::create_dir("docs/src/utils/") { + Err(e) if e.kind() == std::io::ErrorKind::AlreadyExists => Ok(()), + x => x, + }?; + + let mut summary = File::create("docs/src/SUMMARY.md")?; + + let _ = write!( + summary, + "# Summary\n\ + \n\ + [Introduction](index.md)\n\ + * [Installation](installation.md)\n\ + * [Contributing](contributing.md)\n\ + \n\ + # Reference\n\ + * [Multi-call binary](multicall.md)\n", + ); + + let mut utils = utils.iter().collect::>(); + utils.sort(); + for (&name, (_, app)) in utils { + if name == "[" { + continue; + } + let p = format!("docs/src/utils/{}.md", name); + if let Ok(f) = File::create(&p) { + write_markdown(f, &mut app(), name)?; + println!("Wrote to '{}'", p); + } else { + println!("Error writing to {}", p); + } + writeln!(summary, "* [{0}](utils/{0}.md)", name)? + } + Ok(()) +} + +fn write_markdown(mut w: impl Write, app: &mut App, name: &str) -> io::Result<()> { + write!(w, "# {}\n\n", name)?; + write_version(&mut w, app)?; + write_usage(&mut w, app, name)?; + write_description(&mut w, app)?; + write_options(&mut w, app) +} + +fn write_version(w: &mut impl Write, app: &App) -> io::Result<()> { + writeln!( + w, + "
version: {}
", + app.render_version().split_once(' ').unwrap().1 + ) +} + +fn write_usage(w: &mut impl Write, app: &mut App, name: &str) -> io::Result<()> { + writeln!(w, "\n```")?; + let mut usage: String = app.render_usage().lines().nth(1).unwrap().trim().into(); + usage = usage.replace(app.get_name(), name); + writeln!(w, "{}", usage)?; + writeln!(w, "```") +} + +fn write_description(w: &mut impl Write, app: &App) -> io::Result<()> { + if let Some(about) = app.get_long_about().or_else(|| app.get_about()) { + writeln!(w, "{}", about) + } else { + Ok(()) + } +} + +fn write_options(w: &mut impl Write, app: &App) -> io::Result<()> { + writeln!(w, "

Options

")?; + write!(w, "
")?; + for arg in app.get_arguments() { + write!(w, "
")?; + let mut first = true; + for l in arg.get_long_and_visible_aliases().unwrap_or_default() { + if !first { + write!(w, ", ")?; + } else { + first = false; + } + write!(w, "")?; + write!(w, "--{}", l)?; + if let Some(names) = arg.get_value_names() { + write!( + w, + "={}", + names + .iter() + .map(|x| format!("<{}>", x)) + .collect::>() + .join(" ") + )?; + } + write!(w, "")?; + } + for s in arg.get_short_and_visible_aliases().unwrap_or_default() { + if !first { + write!(w, ", ")?; + } else { + first = false; + } + write!(w, "")?; + write!(w, "-{}", s)?; + if let Some(names) = arg.get_value_names() { + write!( + w, + " {}", + names + .iter() + .map(|x| format!("<{}>", x)) + .collect::>() + .join(" ") + )?; + } + write!(w, "")?; + } + writeln!(w, "
")?; + writeln!(w, "
\n\n{}\n\n
", arg.get_help().unwrap_or_default())?; + } + writeln!(w, "
") +} diff --git a/src/uu/sum/src/sum.rs b/src/uu/sum/src/sum.rs index 67bff31b0..1c2b19ba5 100644 --- a/src/uu/sum/src/sum.rs +++ b/src/uu/sum/src/sum.rs @@ -19,9 +19,9 @@ use uucore::error::{FromIo, UResult, USimpleError}; use uucore::InvalidEncodingHandling; static NAME: &str = "sum"; -static USAGE: &str = - "[OPTION]... [FILE]...\nWith no FILE, or when FILE is -, read standard input."; -static SUMMARY: &str = "Checksum and count the blocks in a file."; +static USAGE: &str = "sum [OPTION]... [FILE]..."; +static SUMMARY: &str = "Checksum and count the blocks in a file.\n\ + With no FILE, or when FILE is -, read standard input."; fn bsd_sum(mut reader: Box) -> (usize, u16) { let mut buf = [0; 1024]; diff --git a/src/uu/unexpand/src/unexpand.rs b/src/uu/unexpand/src/unexpand.rs index 83220a012..812375117 100644 --- a/src/uu/unexpand/src/unexpand.rs +++ b/src/uu/unexpand/src/unexpand.rs @@ -22,8 +22,8 @@ use uucore::InvalidEncodingHandling; static NAME: &str = "unexpand"; static USAGE: &str = "unexpand [OPTION]... [FILE]..."; -static SUMMARY: &str = "Convert blanks in each FILE to tabs, writing to standard output.\n - With no FILE, or when FILE is -, read standard input."; +static SUMMARY: &str = "Convert blanks in each FILE to tabs, writing to standard output.\n\ + With no FILE, or when FILE is -, read standard input."; const DEFAULT_TABSTOP: usize = 8;