diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index 847cf6895..49eb61fa7 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -1,7 +1,7 @@ name: CICD # spell-checker:ignore (acronyms) CICD MSVC musl -# spell-checker:ignore (env/flags) Ccodegen Coverflow Cpanic RUSTDOCFLAGS RUSTFLAGS Zpanic +# spell-checker:ignore (env/flags) Awarnings Ccodegen Coverflow Cpanic RUSTDOCFLAGS RUSTFLAGS Zpanic # spell-checker:ignore (jargon) SHAs deps softprops toolchain # spell-checker:ignore (names) CodeCOV MacOS MinGW Peltoche rivy # spell-checker:ignore (shell/tools) choco clippy dmake dpkg esac fakeroot gmake grcov halium lcov libssl mkdir popd printf pushd rustc rustfmt rustup shopt xargs @@ -145,10 +145,6 @@ jobs: cargo fetch --locked --quiet ## * using the 'stable' toolchain is necessary to avoid "unexpected '--filter-platform'" errors RUSTUP_TOOLCHAIN=stable cargo-tree tree --frozen --all --no-dev-dependencies --no-indent --features ${{ matrix.job.features }} | grep -vE "$PWD" | sort --unique - - name: Info - shell: bash - run: | - # Info - name: Test uses: actions-rs/cargo@v1 diff --git a/.vscode/cSpell.json b/.vscode/cSpell.json index 6319d3d59..8561d69ad 100644 --- a/.vscode/cSpell.json +++ b/.vscode/cSpell.json @@ -8,6 +8,8 @@ "Cygwin", "FreeBSD", "Gmail", + "GNUEABI", + "GNUEABIhf", "Irix", "MacOS", "MinGW", @@ -23,16 +25,31 @@ "Xenix", "flac", "lzma", + // cargo + "cdylib", + "rlib", // crates + "advapi", + "advapi32-sys", + "aho-corasick", + "backtrace", "byteorder", + "chacha", "chrono", + "conv", + "corasick", "filetime", "formatteriteminfo", "getopts", "itertools", + "memchr", "multifilereader", "onig", "peekreader", + "quickcheck", + "rand_chacha", + "smallvec", + "tempfile", "termion", "termios", "termsize", @@ -64,12 +81,14 @@ "colorize", "consts", "dedup", + "demangle", "deque", "dequeue", "enqueue", "executable", "executables", "gibibytes", + "hardfloat", "hardlink", "hardlinks", "hashsums", @@ -87,9 +106,12 @@ "primality", "pseudoprime", "pseudoprimes", + "procs", "readonly", "seedable", "semver", + "shortcode", + "shortcodes", "symlink", "symlinks", "syscall", @@ -144,6 +166,7 @@ "Sunrin SHIMURA", "Sunrin", "SHIMURA", "Smigle00", "Smigle", "Sylvestre Ledru", "Sylvestre", "Ledru", + "T Jameson Little", "Jameson", "Little", "Tobias Bohumir Schottdorf", "Tobias", "Bohumir", "Schottdorf", "Virgile Andreani", "Virgile", "Andreani", "Vsevolod Velichko", "Vsevolod", "Velichko", @@ -151,27 +174,37 @@ "Yury Krivopalov", "Yury", "Krivopalov", "anonymousknight", "kwantam", + "nicoo", + "rivy", // rust "clippy", "concat", + "fract", "powi", + "println", "repr", "rfind", "rustc", "rustfmt", + "struct", + "structs", "substr", "splitn", + "trunc", // shell "passwd", + "pipefail", "tcsh", // tags "Maint", // uutils + "chcon", "chgrp", "chmod", "chown", "chroot", "cksum", + "csplit", "dircolors", "hashsum", "hostid", @@ -190,16 +223,28 @@ "realpath", "relpath", "rmdir", + "runcon", "shuf", "stdbuf", + "stty", "tsort", "uname", "unexpand", "whoami", + // vars/errno + "errno", + "EOPNOTSUPP", + // vars/fcntl + "F_GETFL", + "GETFL", + "fcntl", + "vmsplice", // vars/libc "FILENO", "HOSTSIZE", "IDSIZE", + "IFIFO", + "IFREG", "IRGRP", "IROTH", "IRUSR", @@ -240,10 +285,16 @@ "socktype", "umask", "waitpid", + // vars/nix + "iovec", + "unistd", // vars/signals "SIGPIPE", // vars/sync "Condvar", + // vars/stat + "fstat", + "stat", // vars/time "Timespec", "nsec", @@ -265,9 +316,11 @@ "errhandlingapi", "fileapi", "handleapi", + "lmcons", "minwindef", "processthreadsapi", "synchapi", + "sysinfoapi", "winbase", "winerror", "winnt", @@ -285,10 +338,12 @@ "coreopts", "coreutils", "libc", + "libstdbuf", "musl", "ucmd", "utmpx", "uucore", + "uucore_procs", "uumain", "uutils" ], diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..7a73a41bf --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 0f3c4138b..f40f1c094 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -202,8 +202,9 @@ dependencies = [ name = "coreutils" version = "0.0.1" dependencies = [ + "cc 1.0.61 (registry+https://github.com/rust-lang/crates.io-index)", "conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "filetime 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", + "filetime 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -311,7 +312,7 @@ dependencies = [ "uu_who 0.0.1", "uu_whoami 0.0.1", "uu_yes 0.0.1", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -549,10 +550,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "filetime" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1359,32 +1360,32 @@ name = "uu_arch" version = "0.0.1" dependencies = [ "platform-info 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] name = "uu_base32" version = "0.0.1" dependencies = [ - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] name = "uu_base64" version = "0.0.1" dependencies = [ - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] name = "uu_basename" version = "0.0.1" dependencies = [ - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1393,16 +1394,16 @@ version = "0.0.1" dependencies = [ "quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "unix_socket 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] name = "uu_chgrp" version = "0.0.1" dependencies = [ - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1411,8 +1412,8 @@ name = "uu_chmod" version = "0.0.1" dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", "walker 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1421,8 +1422,8 @@ name = "uu_chown" version = "0.0.1" dependencies = [ "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1431,8 +1432,8 @@ name = "uu_chroot" version = "0.0.1" dependencies = [ "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1440,8 +1441,8 @@ name = "uu_cksum" version = "0.0.1" dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1450,8 +1451,8 @@ version = "0.0.1" dependencies = [ "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1459,12 +1460,12 @@ name = "uu_cp" version = "0.0.1" dependencies = [ "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "filetime 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", + "filetime 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", "ioctl-sys 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1474,8 +1475,8 @@ dependencies = [ name = "uu_cut" version = "0.0.1" dependencies = [ - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1484,8 +1485,8 @@ version = "0.0.1" dependencies = [ "chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1495,8 +1496,8 @@ dependencies = [ "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "number_prefix 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1505,8 +1506,8 @@ name = "uu_dircolors" version = "0.0.1" dependencies = [ "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1514,8 +1515,8 @@ name = "uu_dirname" version = "0.0.1" dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1523,16 +1524,16 @@ name = "uu_du" version = "0.0.1" dependencies = [ "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] name = "uu_echo" version = "0.0.1" dependencies = [ - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1542,8 +1543,8 @@ dependencies = [ "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "rust-ini 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1552,8 +1553,8 @@ version = "0.0.1" dependencies = [ "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1562,8 +1563,8 @@ version = "0.0.1" dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "onig 4.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1577,16 +1578,16 @@ dependencies = [ "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] name = "uu_false" version = "0.0.1" dependencies = [ - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1595,16 +1596,16 @@ version = "0.0.1" dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] name = "uu_fold" version = "0.0.1" dependencies = [ - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1612,8 +1613,8 @@ name = "uu_groups" version = "0.0.1" dependencies = [ "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1630,8 +1631,8 @@ dependencies = [ "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "sha2 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "sha3 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1639,8 +1640,8 @@ name = "uu_head" version = "0.0.1" dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1648,8 +1649,8 @@ name = "uu_hostid" version = "0.0.1" dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1659,8 +1660,8 @@ dependencies = [ "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", "hostname 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1668,19 +1669,19 @@ dependencies = [ name = "uu_id" version = "0.0.1" dependencies = [ - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] name = "uu_install" version = "0.0.1" dependencies = [ - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1688,8 +1689,8 @@ name = "uu_join" version = "0.0.1" dependencies = [ "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1697,8 +1698,8 @@ name = "uu_kill" version = "0.0.1" dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1706,8 +1707,8 @@ name = "uu_link" version = "0.0.1" dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1715,8 +1716,8 @@ name = "uu_ln" version = "0.0.1" dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1724,8 +1725,8 @@ name = "uu_logname" version = "0.0.1" dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1740,18 +1741,18 @@ dependencies = [ "termsize 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] name = "uu_mkdir" version = "0.0.1" dependencies = [ - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1760,8 +1761,8 @@ version = "0.0.1" dependencies = [ "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1770,8 +1771,8 @@ version = "0.0.1" dependencies = [ "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1781,8 +1782,8 @@ dependencies = [ "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1793,8 +1794,8 @@ dependencies = [ "nix 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)", "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1803,8 +1804,8 @@ version = "0.0.1" dependencies = [ "fs_extra 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1813,8 +1814,8 @@ version = "0.0.1" dependencies = [ "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1827,8 +1828,8 @@ dependencies = [ "memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1837,8 +1838,8 @@ version = "0.0.1" dependencies = [ "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1848,8 +1849,8 @@ dependencies = [ "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1857,8 +1858,8 @@ name = "uu_numfmt" version = "0.0.1" dependencies = [ "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1869,8 +1870,8 @@ dependencies = [ "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "half 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1878,8 +1879,8 @@ name = "uu_paste" version = "0.0.1" dependencies = [ "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1888,16 +1889,16 @@ version = "0.0.1" dependencies = [ "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] name = "uu_pinky" version = "0.0.1" dependencies = [ - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1905,8 +1906,8 @@ name = "uu_printenv" version = "0.0.1" dependencies = [ "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1914,8 +1915,8 @@ name = "uu_printf" version = "0.0.1" dependencies = [ "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1928,8 +1929,8 @@ dependencies = [ "memchr 2.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1937,8 +1938,8 @@ name = "uu_pwd" version = "0.0.1" dependencies = [ "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1947,8 +1948,8 @@ version = "0.0.1" dependencies = [ "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1956,8 +1957,8 @@ name = "uu_realpath" version = "0.0.1" dependencies = [ "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1965,18 +1966,18 @@ name = "uu_relpath" version = "0.0.1" dependencies = [ "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] name = "uu_rm" version = "0.0.1" dependencies = [ - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", "remove_dir_all 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1985,8 +1986,8 @@ name = "uu_rmdir" version = "0.0.1" dependencies = [ "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -1994,21 +1995,21 @@ name = "uu_seq" version = "0.0.1" dependencies = [ "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] name = "uu_shred" version = "0.0.1" dependencies = [ - "filetime 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", + "filetime 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -2017,8 +2018,8 @@ version = "0.0.1" dependencies = [ "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -2026,8 +2027,8 @@ name = "uu_sleep" version = "0.0.1" dependencies = [ "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -2037,8 +2038,8 @@ dependencies = [ "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -2046,8 +2047,8 @@ name = "uu_split" version = "0.0.1" dependencies = [ "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -2056,8 +2057,8 @@ version = "0.0.1" dependencies = [ "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -2067,8 +2068,8 @@ dependencies = [ "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "uu_stdbuf_libstdbuf 0.0.1", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -2078,8 +2079,8 @@ dependencies = [ "cpp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "cpp_build 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -2087,18 +2088,18 @@ name = "uu_sum" version = "0.0.1" dependencies = [ "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] name = "uu_sync" version = "0.0.1" dependencies = [ - "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2107,8 +2108,8 @@ name = "uu_tac" version = "0.0.1" dependencies = [ "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -2118,8 +2119,8 @@ dependencies = [ "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2129,8 +2130,8 @@ version = "0.0.1" dependencies = [ "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -2139,8 +2140,8 @@ version = "0.0.1" dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.57 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -2150,19 +2151,19 @@ dependencies = [ "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] name = "uu_touch" version = "0.0.1" dependencies = [ - "filetime 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", + "filetime 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -2172,16 +2173,16 @@ dependencies = [ "bit-set 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] name = "uu_true" version = "0.0.1" dependencies = [ - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -2189,8 +2190,8 @@ name = "uu_truncate" version = "0.0.1" dependencies = [ "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -2198,8 +2199,8 @@ name = "uu_tsort" version = "0.0.1" dependencies = [ "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -2208,8 +2209,8 @@ version = "0.0.1" dependencies = [ "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -2218,8 +2219,8 @@ version = "0.0.1" dependencies = [ "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", "platform-info 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -2228,8 +2229,8 @@ version = "0.0.1" dependencies = [ "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -2237,8 +2238,8 @@ name = "uu_uniq" version = "0.0.1" dependencies = [ "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -2247,8 +2248,8 @@ version = "0.0.1" dependencies = [ "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -2258,8 +2259,8 @@ dependencies = [ "chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -2267,8 +2268,8 @@ name = "uu_users" version = "0.0.1" dependencies = [ "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -2276,16 +2277,16 @@ name = "uu_wc" version = "0.0.1" dependencies = [ "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] name = "uu_who" version = "0.0.1" dependencies = [ - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] @@ -2294,8 +2295,8 @@ version = "0.0.1" dependencies = [ "advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2304,14 +2305,13 @@ name = "uu_yes" version = "0.0.1" dependencies = [ "clap 2.33.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", - "uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)", + "uucore 0.0.4", + "uucore_procs 0.0.4", ] [[package]] name = "uucore" version = "0.0.4" -source = "git+https://github.com/uutils/uucore.git?branch=canary#869573459f00ba0b4af9f7d828370c105f31a94e" dependencies = [ "backtrace 0.3.30 (registry+https://github.com/rust-lang/crates.io-index)", "data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2331,7 +2331,6 @@ dependencies = [ [[package]] name = "uucore_procs" version = "0.0.4" -source = "git+https://github.com/uutils/uucore.git?branch=canary#869573459f00ba0b4af9f7d828370c105f31a94e" dependencies = [ "proc-macro2 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2531,7 +2530,7 @@ dependencies = [ "checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82" "checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b" "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" -"checksum filetime 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "3ed85775dcc68644b5c950ac06a2b23768d3bc9390464151aaf27136998dcf9e" +"checksum filetime 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "0c122a393ea57648015bf06fbd3d372378992e86b9ff5a7a497b076a28c79efe" "checksum fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" "checksum fs_extra 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394" "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" @@ -2635,8 +2634,6 @@ dependencies = [ "checksum unindent 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f14ee04d9415b52b3aeab06258a3f07093182b88ba0f9b8d203f211a7a7d41c7" "checksum unix_socket 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6aa2700417c405c38f5e6902d699345241c28c0b7ade4abaad71e35a87eb1564" "checksum users 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aa4227e95324a443c9fcb06e03d4d85e91aabe9a5a02aa818688b6918b6af486" -"checksum uucore 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)" = "" -"checksum uucore_procs 0.0.4 (git+https://github.com/uutils/uucore.git?branch=canary)" = "" "checksum vec_map 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" diff --git a/Cargo.toml b/Cargo.toml index bcf9a7615..1e6172d49 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -225,7 +225,7 @@ test = [ "uu_test" ] [dependencies] 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.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="src/uucore" } # * uutils uu_test = { optional=true, version="0.0.1", package="uu_test", path="src/uu/test" } # @@ -324,6 +324,7 @@ whoami = { optional=true, version="0.0.1", package="uu_whoami", path="src/uu/w yes = { optional=true, version="0.0.1", package="uu_yes", path="src/uu/yes" } # # * pinned transitive dependencies +pin_cc = { version="1.0.61, < 1.0.62", package="cc" } ## cc v1.0.62 has compiler errors for MinRustV v1.32.0, requires 1.34 (for `std::str::split_ascii_whitespace()`) pin_rustc-demangle = { version="0.1.16, < 0.1.17", package="rustc-demangle" } ## rust-demangle v0.1.17 has compiler errors for MinRustV v1.32.0, expects 1.33 pin_same-file = { version="1.0.4, < 1.0.6", package="same-file" } ## same-file v1.0.6 has compiler errors for MinRustV v1.32.0, expects 1.34 pin_winapi-util = { version="0.1.2, < 0.1.3", package="winapi-util" } ## winapi-util v0.1.3 has compiler errors for MinRustV v1.32.0, expects 1.34 @@ -338,7 +339,7 @@ sha1 = { version="0.6", features=["std"] } tempfile = "3.1" time = "0.1" unindent = "0.1" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["entries"] } +uucore = { version=">=0.0.4", package="uucore", path="src/uucore", features=["entries"] } [target.'cfg(unix)'.dev-dependencies] rust-users = { version="0.10", package="users" } diff --git a/src/uu/arch/Cargo.toml b/src/uu/arch/Cargo.toml index 9ab1da6dc..401e7dcdf 100644 --- a/src/uu/arch/Cargo.toml +++ b/src/uu/arch/Cargo.toml @@ -16,8 +16,8 @@ path = "src/arch.rs" [dependencies] platform-info = "0.0.1" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "arch" diff --git a/src/uu/base32/Cargo.toml b/src/uu/base32/Cargo.toml index ea1482858..57620eb0a 100644 --- a/src/uu/base32/Cargo.toml +++ b/src/uu/base32/Cargo.toml @@ -15,8 +15,8 @@ edition = "2018" path = "src/base32.rs" [dependencies] -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features = ["encoding"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features = ["encoding"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "base32" diff --git a/src/uu/base64/Cargo.toml b/src/uu/base64/Cargo.toml index ea83605a0..afc1ecbdc 100644 --- a/src/uu/base64/Cargo.toml +++ b/src/uu/base64/Cargo.toml @@ -15,8 +15,8 @@ edition = "2018" path = "src/base64.rs" [dependencies] -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features = ["encoding"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features = ["encoding"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "base64" diff --git a/src/uu/basename/Cargo.toml b/src/uu/basename/Cargo.toml index 8373c9fc6..943b229cd 100644 --- a/src/uu/basename/Cargo.toml +++ b/src/uu/basename/Cargo.toml @@ -15,8 +15,8 @@ edition = "2018" path = "src/basename.rs" [dependencies] -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "basename" diff --git a/src/uu/cat/Cargo.toml b/src/uu/cat/Cargo.toml index 02f7354c3..4d6006520 100644 --- a/src/uu/cat/Cargo.toml +++ b/src/uu/cat/Cargo.toml @@ -16,8 +16,8 @@ path = "src/cat.rs" [dependencies] quick-error = "1.2.3" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["fs"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["fs"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [target.'cfg(unix)'.dependencies] unix_socket = "0.5.0" diff --git a/src/uu/chgrp/Cargo.toml b/src/uu/chgrp/Cargo.toml index 4e5b6b3b2..bd6194bf6 100644 --- a/src/uu/chgrp/Cargo.toml +++ b/src/uu/chgrp/Cargo.toml @@ -15,8 +15,8 @@ edition = "2018" path = "src/chgrp.rs" [dependencies] -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["entries", "fs"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["entries", "fs"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } walkdir = "2.2.8" [[bin]] diff --git a/src/uu/chmod/Cargo.toml b/src/uu/chmod/Cargo.toml index eff0cc186..3c257cd4d 100644 --- a/src/uu/chmod/Cargo.toml +++ b/src/uu/chmod/Cargo.toml @@ -16,8 +16,8 @@ path = "src/chmod.rs" [dependencies] libc = "0.2.42" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["fs", "mode"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["fs", "mode"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } walker = "1.0.0" [[bin]] diff --git a/src/uu/chown/Cargo.toml b/src/uu/chown/Cargo.toml index 5b3148b28..ebc494761 100644 --- a/src/uu/chown/Cargo.toml +++ b/src/uu/chown/Cargo.toml @@ -16,8 +16,8 @@ path = "src/chown.rs" [dependencies] glob = "0.3.0" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["entries", "fs"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["entries", "fs"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } walkdir = "2.2" [[bin]] diff --git a/src/uu/chroot/Cargo.toml b/src/uu/chroot/Cargo.toml index b8a931c09..e1d168dfe 100644 --- a/src/uu/chroot/Cargo.toml +++ b/src/uu/chroot/Cargo.toml @@ -16,8 +16,8 @@ path = "src/chroot.rs" [dependencies] getopts = "0.2.18" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["entries"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["entries"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "chroot" diff --git a/src/uu/cksum/Cargo.toml b/src/uu/cksum/Cargo.toml index ae6b29534..bc8853287 100644 --- a/src/uu/cksum/Cargo.toml +++ b/src/uu/cksum/Cargo.toml @@ -16,8 +16,8 @@ path = "src/cksum.rs" [dependencies] libc = "0.2.42" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "cksum" diff --git a/src/uu/comm/Cargo.toml b/src/uu/comm/Cargo.toml index 57cdbc0c4..01006d3d0 100644 --- a/src/uu/comm/Cargo.toml +++ b/src/uu/comm/Cargo.toml @@ -17,8 +17,8 @@ path = "src/comm.rs" [dependencies] getopts = "0.2.18" libc = "0.2.42" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "comm" diff --git a/src/uu/cp/Cargo.toml b/src/uu/cp/Cargo.toml index 9fa97ccb0..9c57d92a5 100644 --- a/src/uu/cp/Cargo.toml +++ b/src/uu/cp/Cargo.toml @@ -23,8 +23,8 @@ clap = "2.32" filetime = "0.2" libc = "0.2.42" quick-error = "1.2.3" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["fs"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["fs"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } walkdir = "2.2.8" [target.'cfg(target_os = "linux")'.dependencies] diff --git a/src/uu/cut/Cargo.toml b/src/uu/cut/Cargo.toml index d504cebb3..f53dd42a0 100644 --- a/src/uu/cut/Cargo.toml +++ b/src/uu/cut/Cargo.toml @@ -15,8 +15,8 @@ edition = "2018" path = "src/cut.rs" [dependencies] -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "cut" diff --git a/src/uu/date/Cargo.toml b/src/uu/date/Cargo.toml index 8c462fb26..d2a335d5b 100644 --- a/src/uu/date/Cargo.toml +++ b/src/uu/date/Cargo.toml @@ -17,8 +17,8 @@ path = "src/date.rs" [dependencies] chrono = "0.4.4" clap = "2.32" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "date" diff --git a/src/uu/df/Cargo.toml b/src/uu/df/Cargo.toml index 4144adb41..25d1433fb 100644 --- a/src/uu/df/Cargo.toml +++ b/src/uu/df/Cargo.toml @@ -18,8 +18,8 @@ path = "src/df.rs" clap = "2.32" libc = "0.2" number_prefix = "0.2" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [target.'cfg(target_os = "windows")'.dependencies] winapi = { version = "0.3", features = ["errhandlingapi", "fileapi", "handleapi", "winerror"] } diff --git a/src/uu/dircolors/Cargo.toml b/src/uu/dircolors/Cargo.toml index a1bb6010e..1ac7f8cc9 100644 --- a/src/uu/dircolors/Cargo.toml +++ b/src/uu/dircolors/Cargo.toml @@ -16,8 +16,8 @@ path = "src/dircolors.rs" [dependencies] glob = "0.3.0" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "dircolors" diff --git a/src/uu/dirname/Cargo.toml b/src/uu/dirname/Cargo.toml index 847666854..1503b1c42 100644 --- a/src/uu/dirname/Cargo.toml +++ b/src/uu/dirname/Cargo.toml @@ -16,8 +16,8 @@ path = "src/dirname.rs" [dependencies] libc = "0.2.42" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "dirname" diff --git a/src/uu/du/Cargo.toml b/src/uu/du/Cargo.toml index 6f14a6a32..a83259b05 100644 --- a/src/uu/du/Cargo.toml +++ b/src/uu/du/Cargo.toml @@ -16,8 +16,8 @@ path = "src/du.rs" [dependencies] time = "0.1.40" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "du" diff --git a/src/uu/echo/Cargo.toml b/src/uu/echo/Cargo.toml index 984f872e8..95e91a7ca 100644 --- a/src/uu/echo/Cargo.toml +++ b/src/uu/echo/Cargo.toml @@ -15,8 +15,8 @@ edition = "2018" path = "src/echo.rs" [dependencies] -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "echo" diff --git a/src/uu/env/Cargo.toml b/src/uu/env/Cargo.toml index de54617f4..a425e77e9 100644 --- a/src/uu/env/Cargo.toml +++ b/src/uu/env/Cargo.toml @@ -18,8 +18,8 @@ path = "src/env.rs" clap = "2.33" libc = "0.2.42" rust-ini = "0.13.0" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "env" diff --git a/src/uu/expand/Cargo.toml b/src/uu/expand/Cargo.toml index 4be65e5f4..9161b44d2 100644 --- a/src/uu/expand/Cargo.toml +++ b/src/uu/expand/Cargo.toml @@ -17,8 +17,8 @@ path = "src/expand.rs" [dependencies] getopts = "0.2.18" unicode-width = "0.1.5" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "expand" diff --git a/src/uu/expr/Cargo.toml b/src/uu/expr/Cargo.toml index 69f350cfd..a9cc9e527 100644 --- a/src/uu/expr/Cargo.toml +++ b/src/uu/expr/Cargo.toml @@ -17,8 +17,8 @@ path = "src/expr.rs" [dependencies] libc = "0.2.42" onig = "~4.3.2" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "expr" diff --git a/src/uu/factor/Cargo.toml b/src/uu/factor/Cargo.toml index a37ee5249..5bc48c8a1 100644 --- a/src/uu/factor/Cargo.toml +++ b/src/uu/factor/Cargo.toml @@ -19,8 +19,8 @@ num-traits = "0.2" # used in src/numerics.rs, which is included by build.rs num-traits = "0.2" rand = { version="0.7", features=["small_rng"] } smallvec = { version="0.6.13, < 1.0" } -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [dev-dependencies] criterion = "0.3" diff --git a/src/uu/false/Cargo.toml b/src/uu/false/Cargo.toml index 784a44666..4eca91584 100644 --- a/src/uu/false/Cargo.toml +++ b/src/uu/false/Cargo.toml @@ -15,8 +15,8 @@ edition = "2018" path = "src/false.rs" [dependencies] -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "false" diff --git a/src/uu/fmt/Cargo.toml b/src/uu/fmt/Cargo.toml index 59bb0e2b7..19b67132f 100644 --- a/src/uu/fmt/Cargo.toml +++ b/src/uu/fmt/Cargo.toml @@ -17,8 +17,8 @@ path = "src/fmt.rs" [dependencies] libc = "0.2.42" unicode-width = "0.1.5" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "fmt" diff --git a/src/uu/fold/Cargo.toml b/src/uu/fold/Cargo.toml index 10493a9ca..745f09426 100644 --- a/src/uu/fold/Cargo.toml +++ b/src/uu/fold/Cargo.toml @@ -15,8 +15,8 @@ edition = "2018" path = "src/fold.rs" [dependencies] -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "fold" diff --git a/src/uu/groups/Cargo.toml b/src/uu/groups/Cargo.toml index fb6d193ed..5d29d2063 100644 --- a/src/uu/groups/Cargo.toml +++ b/src/uu/groups/Cargo.toml @@ -15,8 +15,8 @@ edition = "2018" path = "src/groups.rs" [dependencies] -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["entries"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["entries"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } clap = "2.32" [[bin]] diff --git a/src/uu/hashsum/Cargo.toml b/src/uu/hashsum/Cargo.toml index aeaac7ac3..a54a2beac 100644 --- a/src/uu/hashsum/Cargo.toml +++ b/src/uu/hashsum/Cargo.toml @@ -25,8 +25,8 @@ regex-syntax = "0.6.7" sha1 = "0.6.0" sha2 = "0.6.0" sha3 = "0.6.0" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "hashsum" diff --git a/src/uu/head/Cargo.toml b/src/uu/head/Cargo.toml index df9f10a72..cbce20c31 100644 --- a/src/uu/head/Cargo.toml +++ b/src/uu/head/Cargo.toml @@ -16,8 +16,8 @@ path = "src/head.rs" [dependencies] libc = "0.2.42" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "head" diff --git a/src/uu/hostid/Cargo.toml b/src/uu/hostid/Cargo.toml index db833ace7..29fd624ab 100644 --- a/src/uu/hostid/Cargo.toml +++ b/src/uu/hostid/Cargo.toml @@ -16,8 +16,8 @@ path = "src/hostid.rs" [dependencies] libc = "0.2.42" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "hostid" diff --git a/src/uu/hostname/Cargo.toml b/src/uu/hostname/Cargo.toml index c0b724acd..d5cecf9bd 100644 --- a/src/uu/hostname/Cargo.toml +++ b/src/uu/hostname/Cargo.toml @@ -18,8 +18,8 @@ path = "src/hostname.rs" clap = "2.32" libc = "0.2.42" hostname = { version = "0.3", features = ["set"] } -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["wide"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["wide"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } winapi = { version="0.3", features=["sysinfoapi", "winsock2"] } [[bin]] diff --git a/src/uu/id/Cargo.toml b/src/uu/id/Cargo.toml index f82a76c44..c5509e71d 100644 --- a/src/uu/id/Cargo.toml +++ b/src/uu/id/Cargo.toml @@ -15,8 +15,8 @@ edition = "2018" path = "src/id.rs" [dependencies] -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["entries", "process"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["entries", "process"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "id" diff --git a/src/uu/install/Cargo.toml b/src/uu/install/Cargo.toml index 3e00a9bd8..93803048b 100644 --- a/src/uu/install/Cargo.toml +++ b/src/uu/install/Cargo.toml @@ -18,10 +18,10 @@ edition = "2018" path = "src/install.rs" [dependencies] -getopts = "0.2.18" +clap = "2.33" libc = ">= 0.2" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["mode"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["mode"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [dev-dependencies] time = "0.1.40" diff --git a/src/uu/install/src/install.rs b/src/uu/install/src/install.rs index 4970689fb..c92ef1bca 100644 --- a/src/uu/install/src/install.rs +++ b/src/uu/install/src/install.rs @@ -7,7 +7,7 @@ // spell-checker:ignore (ToDO) rwxr sourcepath targetpath -extern crate getopts; +extern crate clap; extern crate libc; mod mode; @@ -15,16 +15,12 @@ mod mode; #[macro_use] extern crate uucore; +use clap::{App, Arg, ArgMatches}; use std::fs; use std::path::{Path, PathBuf}; use std::result::Result; -static NAME: &str = "install"; -static SUMMARY: &str = "Copy SOURCE to DEST or multiple SOURCE(s) to the existing - DIRECTORY, while setting permission modes and owner/group"; -static LONG_HELP: &str = ""; - -const DEFAULT_MODE: u32 = 755; +const DEFAULT_MODE: u32 = 0o755; #[allow(dead_code)] pub struct Behavior { @@ -52,14 +48,179 @@ impl Behavior { } } +static ABOUT: &str = "Copy SOURCE to DEST or multiple SOURCE(s) to the existing + DIRECTORY, while setting permission modes and owner/group"; +static VERSION: &str = env!("CARGO_PKG_VERSION"); + +static OPT_COMPARE: &str = "compare"; +static OPT_BACKUP: &str = "backup"; +static OPT_BACKUP_2: &str = "backup2"; +static OPT_DIRECTORY: &str = "directory"; +static OPT_IGNORED: &str = "ignored"; +static OPT_CREATED: &str = "created"; +static OPT_GROUP: &str = "group"; +static OPT_MODE: &str = "mode"; +static OPT_OWNER: &str = "owner"; +static OPT_PRESERVE_TIMESTAMPS: &str = "preserve-timestamps"; +static OPT_STRIP: &str = "strip"; +static OPT_STRIP_PROGRAM: &str = "strip-program"; +static OPT_SUFFIX: &str = "suffix"; +static OPT_TARGET_DIRECTORY: &str = "target-directory"; +static OPT_NO_TARGET_DIRECTORY: &str = "no-target-directory"; +static OPT_VERBOSE: &str = "verbose"; +static OPT_PRESERVE_CONTEXT: &str = "preserve-context"; +static OPT_CONTEXT: &str = "context"; + +static ARG_FILES: &str = "files"; + +fn get_usage() -> String { + format!("{0} [OPTION]... [FILE]...", executable!()) +} + /// Main install utility function, called from main.rs. /// /// Returns a program return code. /// pub fn uumain(args: impl uucore::Args) -> i32 { - let args = args.collect_str(); + let usage = get_usage(); - let matches = parse_opts(args); + let matches = App::new(executable!()) + .version(VERSION) + .about(ABOUT) + .usage(&usage[..]) + .arg( + Arg::with_name(OPT_BACKUP) + .long(OPT_BACKUP) + .help("(unimplemented) make a backup of each existing destination file") + .value_name("CONTROL") + ) + .arg( + // TODO implement flag + Arg::with_name(OPT_BACKUP_2) + .short("b") + .help("(unimplemented) like --backup but does not accept an argument") + ) + .arg( + Arg::with_name(OPT_IGNORED) + .short("c") + .help("ignored") + ) + .arg( + // TODO implement flag + Arg::with_name(OPT_COMPARE) + .short("C") + .long(OPT_COMPARE) + .help("(unimplemented) compare each pair of source and destination files, and in some cases, do not modify the destination at all") + ) + .arg( + Arg::with_name(OPT_DIRECTORY) + .short("d") + .long(OPT_DIRECTORY) + .help("treat all arguments as directory names. create all components of the specified directories") + ) + + .arg( + // TODO implement flag + Arg::with_name(OPT_CREATED) + .short("D") + .help("(unimplemented) create all leading components of DEST except the last, then copy SOURCE to DEST") + ) + .arg( + // TODO implement flag + Arg::with_name(OPT_GROUP) + .short("g") + .long(OPT_GROUP) + .help("(unimplemented) set group ownership, instead of process's current group") + .value_name("GROUP") + ) + .arg( + Arg::with_name(OPT_MODE) + .short("m") + .long(OPT_MODE) + .help("set permission mode (as in chmod), instead of rwxr-xr-x") + .value_name("MODE") + ) + .arg( + // TODO implement flag + Arg::with_name(OPT_OWNER) + .short("o") + .long(OPT_OWNER) + .help("(unimplemented) set ownership (super-user only)") + .value_name("OWNER") + ) + .arg( + // TODO implement flag + Arg::with_name(OPT_PRESERVE_TIMESTAMPS) + .short("p") + .long(OPT_PRESERVE_TIMESTAMPS) + .help("(unimplemented) apply access/modification times of SOURCE files to corresponding destination files") + ) + .arg( + // TODO implement flag + Arg::with_name(OPT_STRIP) + .short("s") + .long(OPT_STRIP) + .help("(unimplemented) strip symbol tables") + ) + .arg( + // TODO implement flag + Arg::with_name(OPT_STRIP_PROGRAM) + .long(OPT_STRIP_PROGRAM) + .help("(unimplemented) program used to strip binaries") + .value_name("PROGRAM") + ) + .arg( + // TODO implement flag + Arg::with_name(OPT_SUFFIX) + .short("S") + .long(OPT_SUFFIX) + .help("(unimplemented) override the usual backup suffix") + .value_name("SUFFIX") + ) + .arg( + // TODO implement flag + Arg::with_name(OPT_TARGET_DIRECTORY) + .short("t") + .long(OPT_TARGET_DIRECTORY) + .help("(unimplemented) move all SOURCE arguments into DIRECTORY") + .value_name("DIRECTORY") + ) + .arg( + // TODO implement flag + Arg::with_name(OPT_NO_TARGET_DIRECTORY) + .short("T") + .long(OPT_NO_TARGET_DIRECTORY) + .help("(unimplemented) treat DEST as a normal file") + + ) + .arg( + Arg::with_name(OPT_VERBOSE) + .short("v") + .long(OPT_VERBOSE) + .help("explain what is being done") + ) + .arg( + // TODO implement flag + Arg::with_name(OPT_PRESERVE_CONTEXT) + .short("P") + .long(OPT_PRESERVE_CONTEXT) + .help("(unimplemented) preserve security context") + ) + .arg( + // TODO implement flag + Arg::with_name(OPT_CONTEXT) + .short("Z") + .long(OPT_CONTEXT) + .help("(unimplemented) set security context of files and directories") + .value_name("CONTEXT") + ) + .arg(Arg::with_name(ARG_FILES).multiple(true).takes_value(true)) + .get_matches_from(args); + + let paths: Vec = matches + .values_of(ARG_FILES) + .map(|v| v.map(ToString::to_string).collect()) + .unwrap_or_default(); if let Err(s) = check_unimplemented(&matches) { show_error!("Unimplemented feature: {}", s); @@ -73,146 +234,12 @@ pub fn uumain(args: impl uucore::Args) -> i32 { } }; - let paths: Vec = { - #[allow(clippy::ptr_arg)] - fn string_to_path(s: &String) -> &Path { - Path::new(s) - }; - let to_owned = |p: &Path| p.to_owned(); - let arguments = matches.free.iter().map(string_to_path); - - arguments.map(to_owned).collect() - }; - match behavior.main_function { - MainFunction::Directory => directory(&paths[..], behavior), - MainFunction::Standard => standard(&paths[..], behavior), + MainFunction::Directory => directory(paths, behavior), + MainFunction::Standard => standard(paths, behavior), } } -/// Build a specification of the command line. -/// -/// Returns a getopts::Options struct. -/// -fn parse_opts(args: Vec) -> getopts::Matches { - let syntax = format!( - "SOURCE DEST - {} SOURCE... DIRECTORY", - NAME - ); - app!(&syntax, SUMMARY, LONG_HELP) - // TODO implement flag - .optflagopt( - "", - "backup", - "(unimplemented) make a backup of each existing destination\n \ - file", - "CONTROL", - ) - // TODO implement flag - .optflag( - "b", - "", - "(unimplemented) like --backup but does not accept an argument", - ) - .optflag("c", "", "ignored") - // TODO implement flag - .optflag( - "C", - "compare", - "(unimplemented) compare each pair of source and destination\n \ - files, and in some cases, do not modify the destination at all", - ) - .optflag( - "d", - "directory", - "treat all arguments as directory names.\n \ - create all components of the specified directories", - ) - // TODO implement flag - .optflag( - "D", - "", - "(unimplemented) create all leading components of DEST except the\n \ - last, then copy SOURCE to DEST", - ) - // TODO implement flag - .optflagopt( - "g", - "group", - "(unimplemented) set group ownership, instead of process's\n \ - current group", - "GROUP", - ) - .optflagopt( - "m", - "mode", - "set permission mode (as in chmod), instead\n \ - of rwxr-xr-x", - "MODE", - ) - // TODO implement flag - .optflagopt( - "o", - "owner", - "(unimplemented) set ownership (super-user only)", - "OWNER", - ) - // TODO implement flag - .optflag( - "p", - "preserve-timestamps", - "(unimplemented) apply access/modification times\n \ - of SOURCE files to corresponding destination files", - ) - // TODO implement flag - .optflag("s", "strip", "(unimplemented) strip symbol tables") - // TODO implement flag - .optflagopt( - "", - "strip-program", - "(unimplemented) program used to strip binaries", - "PROGRAM", - ) - // TODO implement flag - .optopt( - "S", - "suffix", - "(unimplemented) override the usual backup suffix", - "SUFFIX", - ) - // TODO implement flag - .optopt( - "t", - "target-directory", - "(unimplemented) move all SOURCE arguments into\n \ - DIRECTORY", - "DIRECTORY", - ) - // TODO implement flag - .optflag( - "T", - "no-target-directory", - "(unimplemented) treat DEST as a normal file", - ) - .optflag("v", "verbose", "explain what is being done") - // TODO implement flag - .optflag( - "P", - "preserve-context", - "(unimplemented) preserve security context", - ) - // TODO implement flag - .optflagopt( - "Z", - "context", - "(unimplemented) set security context of files and\n \ - directories", - "CONTEXT", - ) - .parse(args) -} - /// Check for unimplemented command line arguments. /// /// Either return the degenerate Ok value, or an Err with string. @@ -221,34 +248,35 @@ fn parse_opts(args: Vec) -> getopts::Matches { /// /// Error datum is a string of the unimplemented argument. /// -fn check_unimplemented(matches: &getopts::Matches) -> Result<(), &str> { - if matches.opt_present("backup") { +/// +fn check_unimplemented<'a>(matches: &ArgMatches) -> Result<(), &'a str> { + if matches.is_present(OPT_BACKUP) { Err("--backup") - } else if matches.opt_present("b") { + } else if matches.is_present(OPT_BACKUP_2) { Err("-b") - } else if matches.opt_present("compare") { + } else if matches.is_present(OPT_COMPARE) { Err("--compare, -C") - } else if matches.opt_present("D") { + } else if matches.is_present(OPT_CREATED) { Err("-D") - } else if matches.opt_present("group") { + } else if matches.is_present(OPT_GROUP) { Err("--group, -g") - } else if matches.opt_present("owner") { + } else if matches.is_present(OPT_OWNER) { Err("--owner, -o") - } else if matches.opt_present("preserve-timestamps") { + } else if matches.is_present(OPT_PRESERVE_TIMESTAMPS) { Err("--preserve-timestamps, -p") - } else if matches.opt_present("strip") { + } else if matches.is_present(OPT_STRIP) { Err("--strip, -s") - } else if matches.opt_present("strip-program") { + } else if matches.is_present(OPT_STRIP_PROGRAM) { Err("--strip-program") - } else if matches.opt_present("suffix") { + } else if matches.is_present(OPT_SUFFIX) { Err("--suffix, -S") - } else if matches.opt_present("target-directory") { + } else if matches.is_present(OPT_TARGET_DIRECTORY) { Err("--target-directory, -t") - } else if matches.opt_present("no-target-directory") { + } else if matches.is_present(OPT_NO_TARGET_DIRECTORY) { Err("--no-target-directory, -T") - } else if matches.opt_present("preserve-context") { + } else if matches.is_present(OPT_PRESERVE_CONTEXT) { Err("--preserve-context, -P") - } else if matches.opt_present("context") { + } else if matches.is_present(OPT_CONTEXT) { Err("--context, -Z") } else { Ok(()) @@ -263,8 +291,8 @@ fn check_unimplemented(matches: &getopts::Matches) -> Result<(), &str> { /// /// In event of failure, returns an integer intended as a program return code. /// -fn behavior(matches: &getopts::Matches) -> Result { - let main_function = if matches.opt_present("directory") { +fn behavior(matches: &ArgMatches) -> Result { + let main_function = if matches.is_present("directory") { MainFunction::Directory } else { MainFunction::Standard @@ -272,8 +300,8 @@ fn behavior(matches: &getopts::Matches) -> Result { let considering_dir: bool = MainFunction::Directory == main_function; - let specified_mode: Option = if matches.opt_present("mode") { - match matches.opt_str("mode") { + let specified_mode: Option = if matches.is_present(OPT_MODE) { + match matches.value_of(OPT_MODE) { Some(x) => match mode::parse(&x[..], considering_dir) { Ok(y) => Some(y), Err(err) => { @@ -285,7 +313,7 @@ fn behavior(matches: &getopts::Matches) -> Result { show_error!( "option '--mode' requires an argument\n \ Try '{} --help' for more information.", - NAME + executable!() ); return Err(1); } @@ -294,27 +322,27 @@ fn behavior(matches: &getopts::Matches) -> Result { None }; - let backup_suffix = if matches.opt_present("suffix") { - match matches.opt_str("suffix") { + let backup_suffix = if matches.is_present(OPT_SUFFIX) { + match matches.value_of(OPT_SUFFIX) { Some(x) => x, None => { show_error!( "option '--suffix' requires an argument\n\ Try '{} --help' for more information.", - NAME + executable!() ); return Err(1); } } } else { - "~".to_owned() + "~" }; Ok(Behavior { main_function, specified_mode, - suffix: backup_suffix, - verbose: matches.opt_present("v"), + suffix: backup_suffix.to_string(), + verbose: matches.is_present(OPT_VERBOSE), }) } @@ -325,15 +353,15 @@ fn behavior(matches: &getopts::Matches) -> Result { /// /// Returns an integer intended as a program return code. /// -fn directory(paths: &[PathBuf], b: Behavior) -> i32 { +fn directory(paths: Vec, b: Behavior) -> i32 { if paths.is_empty() { - println!("{} with -d requires at least one argument.", NAME); + println!("{} with -d requires at least one argument.", executable!()); 1 } else { let mut all_successful = true; for directory in paths.iter() { - let path = directory.as_path(); + let path = Path::new(directory); if path.exists() { show_info!("cannot create directory '{}': File exists", path.display()); @@ -371,18 +399,21 @@ fn is_new_file_path(path: &Path) -> bool { /// /// Returns an integer intended as a program return code. /// -fn standard(paths: &[PathBuf], b: Behavior) -> i32 { +fn standard(paths: Vec, b: Behavior) -> i32 { if paths.len() < 2 { - println!("{} requires at least 2 arguments.", NAME); + println!("{} requires at least 2 arguments.", executable!()); 1 } else { - let sources = &paths[0..paths.len() - 1]; - let target = &paths[paths.len() - 1]; + let sources = &paths[0..paths.len() - 1] + .iter() + .map(PathBuf::from) + .collect::>(); + let target = Path::new(paths.last().unwrap()); if (target.is_file() || is_new_file_path(target)) && sources.len() == 1 { - copy_file_to_file(&sources[0], target, &b) + copy_file_to_file(&sources[0], &target.to_path_buf(), &b) } else { - copy_files_into_dir(sources, target, &b) + copy_files_into_dir(sources, &target.to_path_buf(), &b) } } } diff --git a/src/uu/join/Cargo.toml b/src/uu/join/Cargo.toml index 156b4429b..7e16ebf2f 100644 --- a/src/uu/join/Cargo.toml +++ b/src/uu/join/Cargo.toml @@ -16,8 +16,8 @@ path = "src/join.rs" [dependencies] clap = "2.32" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "join" diff --git a/src/uu/kill/Cargo.toml b/src/uu/kill/Cargo.toml index 1562ffb8a..60566685b 100644 --- a/src/uu/kill/Cargo.toml +++ b/src/uu/kill/Cargo.toml @@ -16,8 +16,8 @@ path = "src/kill.rs" [dependencies] libc = "0.2.42" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["signals"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["signals"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "kill" diff --git a/src/uu/link/Cargo.toml b/src/uu/link/Cargo.toml index 9b9f08f94..3af0e5a50 100644 --- a/src/uu/link/Cargo.toml +++ b/src/uu/link/Cargo.toml @@ -16,8 +16,8 @@ path = "src/link.rs" [dependencies] libc = "0.2.42" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "link" diff --git a/src/uu/ln/Cargo.toml b/src/uu/ln/Cargo.toml index 2a26ca938..14846dcd3 100644 --- a/src/uu/ln/Cargo.toml +++ b/src/uu/ln/Cargo.toml @@ -16,8 +16,8 @@ path = "src/ln.rs" [dependencies] libc = "0.2.42" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "ln" diff --git a/src/uu/logname/Cargo.toml b/src/uu/logname/Cargo.toml index 450ac4571..722824328 100644 --- a/src/uu/logname/Cargo.toml +++ b/src/uu/logname/Cargo.toml @@ -16,8 +16,8 @@ path = "src/logname.rs" [dependencies] libc = "0.2.42" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "logname" diff --git a/src/uu/ls/Cargo.toml b/src/uu/ls/Cargo.toml index f35f90dc1..93ccefe68 100644 --- a/src/uu/ls/Cargo.toml +++ b/src/uu/ls/Cargo.toml @@ -23,8 +23,8 @@ term_grid = "0.1.5" termsize = "0.1.6" time = "0.1.40" unicode-width = "0.1.5" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["entries", "fs"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["entries", "fs"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "ls" diff --git a/src/uu/mkdir/Cargo.toml b/src/uu/mkdir/Cargo.toml index 89c391fb0..90dde5238 100644 --- a/src/uu/mkdir/Cargo.toml +++ b/src/uu/mkdir/Cargo.toml @@ -15,10 +15,10 @@ edition = "2018" path = "src/mkdir.rs" [dependencies] -getopts = "0.2.18" +clap = "2.33" libc = "0.2.42" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["fs", "mode"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["fs", "mode"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "mkdir" diff --git a/src/uu/mkdir/src/mkdir.rs b/src/uu/mkdir/src/mkdir.rs index c1c03d8f2..7e53ed8e7 100644 --- a/src/uu/mkdir/src/mkdir.rs +++ b/src/uu/mkdir/src/mkdir.rs @@ -5,53 +5,78 @@ // * For the full copyright and license information, please view the LICENSE // * file that was distributed with this source code. -extern crate getopts; +extern crate clap; #[macro_use] extern crate uucore; +use clap::{App, Arg}; use std::fs; use std::path::Path; -static NAME: &str = "mkdir"; +static ABOUT: &str = "Create the given DIRECTORY(ies) if they do not exist"; static VERSION: &str = env!("CARGO_PKG_VERSION"); +static OPT_MODE: &str = "mode"; +static OPT_PARENTS: &str = "parents"; +static OPT_VERBOSE: &str = "verbose"; + +static ARG_DIRS: &str = "dirs"; + +fn get_usage() -> String { + format!("{0} [OPTION]... [USER]", executable!()) +} /** * Handles option parsing */ pub fn uumain(args: impl uucore::Args) -> i32 { - let args = args.collect_str(); - - let mut opts = getopts::Options::new(); + let usage = get_usage(); // Linux-specific options, not implemented // opts.optflag("Z", "context", "set SELinux security context" + // " of each created directory to CTX"), - opts.optopt("m", "mode", "set file mode", "755"); - opts.optflag("p", "parents", "make parent directories as needed"); - opts.optflag("v", "verbose", "print a message for each printed directory"); - opts.optflag("h", "help", "display this help"); - opts.optflag("V", "version", "display this version"); + let matches = App::new(executable!()) + .version(VERSION) + .about(ABOUT) + .usage(&usage[..]) + .arg( + Arg::with_name(OPT_MODE) + .short("m") + .long(OPT_MODE) + .help("set file mode") + .default_value("755"), + ) + .arg( + Arg::with_name(OPT_PARENTS) + .short("p") + .long(OPT_PARENTS) + .help("make parent directories as needed"), + ) + .arg( + Arg::with_name(OPT_VERBOSE) + .short("v") + .long(OPT_VERBOSE) + .help("print a message for each printed directory"), + ) + .arg( + Arg::with_name(ARG_DIRS) + .multiple(true) + .takes_value(true) + .min_values(1), + ) + .get_matches_from(args); - let matches = match opts.parse(&args[1..]) { - Ok(m) => m, - Err(f) => crash!(1, "Invalid options\n{}", f), - }; + let dirs: Vec = matches + .values_of(ARG_DIRS) + .map(|v| v.map(ToString::to_string).collect()) + .unwrap_or_default(); - if args.len() == 1 || matches.opt_present("help") { - print_help(&opts); - return 0; - } - if matches.opt_present("version") { - println!("{} {}", NAME, VERSION); - return 0; - } - let verbose = matches.opt_present("verbose"); - let recursive = matches.opt_present("parents"); + let verbose = matches.is_present(OPT_VERBOSE); + let recursive = matches.is_present(OPT_PARENTS); // Translate a ~str in octal form to u16, default to 755 // Not tested on Windows - let mode_match = matches.opts_str(&["mode".to_owned()]); + let mode_match = matches.value_of(OPT_MODE); let mode: u16 = match mode_match { Some(m) => { let res: Option = u16::from_str_radix(&m, 8).ok(); @@ -63,23 +88,9 @@ pub fn uumain(args: impl uucore::Args) -> i32 { _ => 0o755 as u16, }; - let dirs = matches.free; - if dirs.is_empty() { - crash!(1, "missing operand"); - } exec(dirs, recursive, mode, verbose) } -fn print_help(opts: &getopts::Options) { - println!("{} {}", NAME, VERSION); - println!(); - println!("Usage:"); - print!( - "{}", - opts.usage("Create the given DIRECTORY(ies) if they do not exist") - ); -} - /** * Create the list of new directories */ @@ -120,7 +131,7 @@ fn mkdir(path: &Path, recursive: bool, mode: u16, verbose: bool) -> i32 { } if verbose { - show_info!("created directory '{}'", path.display()); + println!("{}: created directory '{}'", executable!(), path.display()); } #[cfg(any(unix, target_os = "redox"))] diff --git a/src/uu/mkfifo/Cargo.toml b/src/uu/mkfifo/Cargo.toml index c06be0dad..97a925663 100644 --- a/src/uu/mkfifo/Cargo.toml +++ b/src/uu/mkfifo/Cargo.toml @@ -17,8 +17,8 @@ path = "src/mkfifo.rs" [dependencies] getopts = "0.2.18" libc = "0.2.42" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "mkfifo" diff --git a/src/uu/mknod/Cargo.toml b/src/uu/mknod/Cargo.toml index d7058b883..e98a9400e 100644 --- a/src/uu/mknod/Cargo.toml +++ b/src/uu/mknod/Cargo.toml @@ -18,8 +18,8 @@ path = "src/mknod.rs" [dependencies] getopts = "0.2.18" libc = "^0.2.42" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["mode"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["mode"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "mknod" diff --git a/src/uu/mktemp/Cargo.toml b/src/uu/mktemp/Cargo.toml index c9a937ba1..b188dbcbe 100644 --- a/src/uu/mktemp/Cargo.toml +++ b/src/uu/mktemp/Cargo.toml @@ -18,8 +18,8 @@ path = "src/mktemp.rs" getopts = "0.2.18" rand = "0.5" tempfile = "3.0" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "mktemp" diff --git a/src/uu/more/Cargo.toml b/src/uu/more/Cargo.toml index 56af9e2df..ca9fc8560 100644 --- a/src/uu/more/Cargo.toml +++ b/src/uu/more/Cargo.toml @@ -16,8 +16,8 @@ path = "src/more.rs" [dependencies] getopts = "0.2.18" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [target.'cfg(target_os = "redox")'.dependencies] redox_termios = "0.1" diff --git a/src/uu/mv/Cargo.toml b/src/uu/mv/Cargo.toml index 708330800..442b859eb 100644 --- a/src/uu/mv/Cargo.toml +++ b/src/uu/mv/Cargo.toml @@ -17,8 +17,8 @@ path = "src/mv.rs" [dependencies] getopts = "0.2.18" fs_extra = "1.1.0" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "mv" diff --git a/src/uu/nice/Cargo.toml b/src/uu/nice/Cargo.toml index e9ca8445a..65addb665 100644 --- a/src/uu/nice/Cargo.toml +++ b/src/uu/nice/Cargo.toml @@ -17,8 +17,8 @@ path = "src/nice.rs" [dependencies] getopts = "0.2.18" libc = "0.2.42" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "nice" diff --git a/src/uu/nl/Cargo.toml b/src/uu/nl/Cargo.toml index 23d12af1e..542b8ae5c 100644 --- a/src/uu/nl/Cargo.toml +++ b/src/uu/nl/Cargo.toml @@ -21,8 +21,8 @@ libc = "0.2.42" memchr = "2.2.0" regex = "1.0.1" regex-syntax = "0.6.7" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "nl" diff --git a/src/uu/nohup/Cargo.toml b/src/uu/nohup/Cargo.toml index d349fd22f..b1df8f1a7 100644 --- a/src/uu/nohup/Cargo.toml +++ b/src/uu/nohup/Cargo.toml @@ -17,8 +17,8 @@ path = "src/nohup.rs" [dependencies] getopts = "0.2.18" libc = "0.2.42" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["fs"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["fs"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "nohup" diff --git a/src/uu/nproc/Cargo.toml b/src/uu/nproc/Cargo.toml index 681fe3032..7bfc7f2e1 100644 --- a/src/uu/nproc/Cargo.toml +++ b/src/uu/nproc/Cargo.toml @@ -18,8 +18,8 @@ path = "src/nproc.rs" libc = "0.2.42" num_cpus = "1.10" clap = "2.33" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["fs"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["fs"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "nproc" diff --git a/src/uu/numfmt/Cargo.toml b/src/uu/numfmt/Cargo.toml index b965b6053..93407980c 100644 --- a/src/uu/numfmt/Cargo.toml +++ b/src/uu/numfmt/Cargo.toml @@ -16,8 +16,8 @@ path = "src/numfmt.rs" [dependencies] getopts = "0.2.18" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "numfmt" diff --git a/src/uu/od/Cargo.toml b/src/uu/od/Cargo.toml index dd58a2b89..611c569a3 100644 --- a/src/uu/od/Cargo.toml +++ b/src/uu/od/Cargo.toml @@ -19,8 +19,8 @@ byteorder = "1.3.2" getopts = "0.2.18" half = "1.6" libc = "0.2.42" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "od" diff --git a/src/uu/paste/Cargo.toml b/src/uu/paste/Cargo.toml index 200e189c3..3f08b722d 100644 --- a/src/uu/paste/Cargo.toml +++ b/src/uu/paste/Cargo.toml @@ -16,8 +16,8 @@ path = "src/paste.rs" [dependencies] getopts = "0.2.18" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "paste" diff --git a/src/uu/pathchk/Cargo.toml b/src/uu/pathchk/Cargo.toml index 3db2a5750..0c1885904 100644 --- a/src/uu/pathchk/Cargo.toml +++ b/src/uu/pathchk/Cargo.toml @@ -17,8 +17,8 @@ path = "src/pathchk.rs" [dependencies] getopts = "0.2.18" libc = "0.2.42" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "pathchk" diff --git a/src/uu/pinky/Cargo.toml b/src/uu/pinky/Cargo.toml index 1f2bfc13b..f4ccf88a2 100644 --- a/src/uu/pinky/Cargo.toml +++ b/src/uu/pinky/Cargo.toml @@ -15,8 +15,8 @@ edition = "2018" path = "src/pinky.rs" [dependencies] -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["utmpx", "entries"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["utmpx", "entries"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "pinky" diff --git a/src/uu/printenv/Cargo.toml b/src/uu/printenv/Cargo.toml index 68db1b689..0292b455b 100644 --- a/src/uu/printenv/Cargo.toml +++ b/src/uu/printenv/Cargo.toml @@ -16,8 +16,8 @@ path = "src/printenv.rs" [dependencies] clap = "2.33" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "printenv" diff --git a/src/uu/printf/Cargo.toml b/src/uu/printf/Cargo.toml index 7ac01a597..a2696486b 100644 --- a/src/uu/printf/Cargo.toml +++ b/src/uu/printf/Cargo.toml @@ -19,8 +19,8 @@ path = "src/printf.rs" [dependencies] itertools = "0.8.0" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "printf" diff --git a/src/uu/ptx/Cargo.toml b/src/uu/ptx/Cargo.toml index e906981c6..5f147c97d 100644 --- a/src/uu/ptx/Cargo.toml +++ b/src/uu/ptx/Cargo.toml @@ -21,8 +21,8 @@ libc = "0.2.42" memchr = "2.2.0" regex = "1.0.1" regex-syntax = "0.6.7" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "ptx" diff --git a/src/uu/pwd/Cargo.toml b/src/uu/pwd/Cargo.toml index ef25017d1..c61e8bc14 100644 --- a/src/uu/pwd/Cargo.toml +++ b/src/uu/pwd/Cargo.toml @@ -16,8 +16,8 @@ path = "src/pwd.rs" [dependencies] getopts = "0.2.18" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "pwd" diff --git a/src/uu/readlink/Cargo.toml b/src/uu/readlink/Cargo.toml index 6a46a09cc..18e83178f 100644 --- a/src/uu/readlink/Cargo.toml +++ b/src/uu/readlink/Cargo.toml @@ -17,8 +17,8 @@ path = "src/readlink.rs" [dependencies] clap = "2.33" libc = "0.2.42" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["fs"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["fs"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "readlink" diff --git a/src/uu/realpath/Cargo.toml b/src/uu/realpath/Cargo.toml index 4cd083c54..808ec1330 100644 --- a/src/uu/realpath/Cargo.toml +++ b/src/uu/realpath/Cargo.toml @@ -16,8 +16,8 @@ path = "src/realpath.rs" [dependencies] getopts = "0.2.18" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["fs"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["fs"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "realpath" diff --git a/src/uu/relpath/Cargo.toml b/src/uu/relpath/Cargo.toml index ff2f3120e..2d4e67fb1 100644 --- a/src/uu/relpath/Cargo.toml +++ b/src/uu/relpath/Cargo.toml @@ -16,8 +16,8 @@ path = "src/relpath.rs" [dependencies] getopts = "0.2.18" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["fs"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["fs"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "relpath" diff --git a/src/uu/rm/Cargo.toml b/src/uu/rm/Cargo.toml index 8fbd14663..8e455eef0 100644 --- a/src/uu/rm/Cargo.toml +++ b/src/uu/rm/Cargo.toml @@ -15,11 +15,11 @@ edition = "2018" path = "src/rm.rs" [dependencies] -getopts = "0.2.18" +clap = "2.33" walkdir = "2.2.8" remove_dir_all = "0.5.1" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "rm" diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index f87f3e1ac..eaacb9555 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -7,13 +7,14 @@ // spell-checker:ignore (ToDO) bitor ulong -extern crate getopts; +extern crate clap; extern crate remove_dir_all; extern crate walkdir; #[macro_use] extern crate uucore; +use clap::{App, Arg}; use remove_dir_all::remove_dir_all; use std::collections::VecDeque; use std::fs; @@ -40,83 +41,139 @@ struct Options { verbose: bool, } -static NAME: &str = "rm"; +static ABOUT: &str = "Remove (unlink) the FILE(s)"; static VERSION: &str = env!("CARGO_PKG_VERSION"); +static OPT_DIR: &str = "dir"; +static OPT_INTERACTIVE: &str = "interactive"; +static OPT_FORCE: &str = "force"; +static OPT_NO_PRESERVE_ROOT: &str = "no-preserve-root"; +static OPT_ONE_FILE_SYSTEM: &str = "one-file-system"; +static OPT_PRESERVE_ROOT: &str = "preserve-root"; +static OPT_PROMPT: &str = "prompt"; +static OPT_PROMPT_MORE: &str = "prompt-more"; +static OPT_RECURSIVE: &str = "recursive"; +static OPT_VERBOSE: &str = "verbose"; + +static ARG_FILES: &str = "files"; + +fn get_usage() -> String { + format!("{0} [OPTION]... FILE...", executable!()) +} + +fn get_long_usage() -> String { + String::from( + "By default, rm does not remove directories. Use the --recursive (-r) + option to remove each listed directory, too, along with all of its contents + + To remove a file whose name starts with a '-', for example '-foo', + use one of these commands: + rm -- -foo + + rm ./-foo + + Note that if you use rm to remove a file, it might be possible to recover + some of its contents, given sufficient expertise and/or time. For greater + assurance that the contents are truly unrecoverable, consider using shred.", + ) +} pub fn uumain(args: impl uucore::Args) -> i32 { - let args = args.collect_str(); + let usage = get_usage(); + let long_usage = get_long_usage(); + let matches = App::new(executable!()) + .version(VERSION) + .about(ABOUT) + .usage(&usage[..]) + .after_help(&long_usage[..]) // TODO: make getopts support -R in addition to -r - let mut opts = getopts::Options::new(); - opts.optflag( - "f", - "force", - "ignore nonexistent files and arguments, never prompt", - ); - opts.optflag("i", "", "prompt before every removal"); - opts.optflag("I", "", "prompt once before removing more than three files, or when removing recursively. Less intrusive than -i, while still giving some protection against most mistakes"); - opts.optflagopt( - "", - "interactive", - "prompt according to WHEN: never, once (-I), or always (-i). Without WHEN, prompts always", - "WHEN", - ); - opts.optflag("", "one-file-system", "when removing a hierarchy recursively, skip any directory that is on a file system different from that of the corresponding command line argument (NOT IMPLEMENTED)"); - opts.optflag("", "no-preserve-root", "do not treat '/' specially"); - opts.optflag("", "preserve-root", "do not remove '/' (default)"); - opts.optflag( - "r", - "recursive", - "remove directories and their contents recursively", - ); - opts.optflag("d", "dir", "remove empty directories"); - opts.optflag("v", "verbose", "explain what is being done"); - opts.optflag("h", "help", "display this help and exit"); - opts.optflag("V", "version", "output version information and exit"); + .arg( + Arg::with_name(OPT_FORCE) + .short("f") + .long(OPT_FORCE) + .help("ignore nonexistent files and arguments, never prompt") + ) + .arg( + Arg::with_name(OPT_PROMPT) + .short("i") + .long("prompt before every removal") + ) + .arg( + Arg::with_name(OPT_PROMPT_MORE) + .short("I") + .help("prompt once before removing more than three files, or when removing recursively. Less intrusive than -i, while still giving some protection against most mistakes") + ) + .arg( + Arg::with_name(OPT_INTERACTIVE) + .long(OPT_INTERACTIVE) + .help("prompt according to WHEN: never, once (-I), or always (-i). Without WHEN, prompts always") + .value_name("WHEN") + .takes_value(true) + ) + .arg( + Arg::with_name(OPT_ONE_FILE_SYSTEM) + .long(OPT_ONE_FILE_SYSTEM) + .help("when removing a hierarchy recursively, skip any directory that is on a file system different from that of the corresponding command line argument (NOT IMPLEMENTED)") + ) + .arg( + Arg::with_name(OPT_NO_PRESERVE_ROOT) + .long(OPT_NO_PRESERVE_ROOT) + .help("do not treat '/' specially") + ) + .arg( + Arg::with_name(OPT_PRESERVE_ROOT) + .long(OPT_PRESERVE_ROOT) + .help("do not remove '/' (default)") + ) + .arg( + Arg::with_name(OPT_RECURSIVE).short("r") + .long(OPT_RECURSIVE) + .help("remove directories and their contents recursively") + ) + .arg( + Arg::with_name(OPT_DIR) + .short("d") + .long(OPT_DIR) + .help("remove empty directories") + ) + .arg( + Arg::with_name(OPT_VERBOSE) + .short("v") + .long(OPT_VERBOSE) + .help("explain what is being done") + ) + .arg( + Arg::with_name(ARG_FILES) + .multiple(true) + .takes_value(true) + .min_values(1) + ) + .get_matches_from(args); - let matches = match opts.parse(&args[1..]) { - Ok(m) => m, - Err(f) => crash!(1, "{}", f), - }; + let files: Vec = matches + .values_of(ARG_FILES) + .map(|v| v.map(ToString::to_string).collect()) + .unwrap_or_default(); - let force = matches.opt_present("force"); + let force = matches.is_present(OPT_FORCE); - if matches.opt_present("help") { - println!("{} {}", NAME, VERSION); - println!(); - println!("Usage:"); - println!(" {0} [OPTION]... [FILE]...", NAME); - println!(); - println!("{}", opts.usage("Remove (unlink) the FILE(s).")); - println!("By default, rm does not remove directories. Use the --recursive (-r)"); - println!("option to remove each listed directory, too, along with all of its contents"); - println!(); - println!("To remove a file whose name starts with a '-', for example '-foo',"); - println!("use one of these commands:"); - println!("rm -- -foo"); - println!(); - println!("rm ./-foo"); - println!(); - println!("Note that if you use rm to remove a file, it might be possible to recover"); - println!("some of its contents, given sufficient expertise and/or time. For greater"); - println!("assurance that the contents are truly unrecoverable, consider using shred."); - } else if matches.opt_present("version") { - println!("{} {}", NAME, VERSION); - } else if matches.free.is_empty() && !force { + if files.is_empty() && !force { + // Still check by hand and not use clap + // Because "rm -f" is a thing show_error!("missing an argument"); - show_error!("for help, try '{0} --help'", NAME); + show_error!("for help, try '{0} --help'", executable!()); return 1; } else { let options = Options { force, interactive: { - if matches.opt_present("i") { + if matches.is_present(OPT_PROMPT) { InteractiveMode::Always - } else if matches.opt_present("I") { + } else if matches.is_present(OPT_PROMPT_MORE) { InteractiveMode::Once - } else if matches.opt_present("interactive") { - match &matches.opt_str("interactive").unwrap()[..] { + } else if matches.is_present(OPT_INTERACTIVE) { + match &matches.value_of(OPT_INTERACTIVE).unwrap()[..] { "none" => InteractiveMode::None, "once" => InteractiveMode::Once, "always" => InteractiveMode::Always, @@ -126,15 +183,13 @@ pub fn uumain(args: impl uucore::Args) -> i32 { InteractiveMode::None } }, - one_fs: matches.opt_present("one-file-system"), - preserve_root: !matches.opt_present("no-preserve-root"), - recursive: matches.opt_present("recursive"), - dir: matches.opt_present("dir"), - verbose: matches.opt_present("verbose"), + one_fs: matches.is_present(OPT_ONE_FILE_SYSTEM), + preserve_root: !matches.is_present(OPT_NO_PRESERVE_ROOT), + recursive: matches.is_present(OPT_RECURSIVE), + dir: matches.is_present(OPT_DIR), + verbose: matches.is_present(OPT_VERBOSE), }; - if options.interactive == InteractiveMode::Once - && (options.recursive || matches.free.len() > 3) - { + if options.interactive == InteractiveMode::Once && (options.recursive || files.len() > 3) { let msg = if options.recursive { "Remove all arguments recursively? " } else { @@ -145,7 +200,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { } } - if remove(matches.free, options) { + if remove(files, options) { return 1; } } diff --git a/src/uu/rmdir/Cargo.toml b/src/uu/rmdir/Cargo.toml index 2c1c15862..60a54f4a9 100644 --- a/src/uu/rmdir/Cargo.toml +++ b/src/uu/rmdir/Cargo.toml @@ -16,8 +16,8 @@ path = "src/rmdir.rs" [dependencies] clap = "2.33" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "rmdir" diff --git a/src/uu/seq/Cargo.toml b/src/uu/seq/Cargo.toml index b7cf3901c..380c6d6d6 100644 --- a/src/uu/seq/Cargo.toml +++ b/src/uu/seq/Cargo.toml @@ -16,8 +16,8 @@ path = "src/seq.rs" [dependencies] clap = "2.33" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "seq" diff --git a/src/uu/shred/Cargo.toml b/src/uu/shred/Cargo.toml index 12cc3926e..bccba633c 100644 --- a/src/uu/shred/Cargo.toml +++ b/src/uu/shred/Cargo.toml @@ -20,8 +20,8 @@ getopts = "0.2.18" libc = "0.2.42" rand = "0.5" time = "0.1.40" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "shred" diff --git a/src/uu/shuf/Cargo.toml b/src/uu/shuf/Cargo.toml index 128fb939c..428c130df 100644 --- a/src/uu/shuf/Cargo.toml +++ b/src/uu/shuf/Cargo.toml @@ -17,8 +17,8 @@ path = "src/shuf.rs" [dependencies] getopts = "0.2.18" rand = "0.5" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "shuf" diff --git a/src/uu/sleep/Cargo.toml b/src/uu/sleep/Cargo.toml index 09d3d1289..e5c300bf6 100644 --- a/src/uu/sleep/Cargo.toml +++ b/src/uu/sleep/Cargo.toml @@ -16,8 +16,8 @@ path = "src/sleep.rs" [dependencies] getopts = "0.2.18" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["parse_time"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["parse_time"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "sleep" diff --git a/src/uu/sort/Cargo.toml b/src/uu/sort/Cargo.toml index fca462b04..01065a931 100644 --- a/src/uu/sort/Cargo.toml +++ b/src/uu/sort/Cargo.toml @@ -18,8 +18,8 @@ path = "src/sort.rs" clap = "2.33" itertools = "0.8.0" semver = "0.9.0" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["fs"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["fs"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "sort" diff --git a/src/uu/split/Cargo.toml b/src/uu/split/Cargo.toml index 90563345a..6076423f3 100644 --- a/src/uu/split/Cargo.toml +++ b/src/uu/split/Cargo.toml @@ -16,8 +16,8 @@ path = "src/split.rs" [dependencies] getopts = "0.2.18" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "split" diff --git a/src/uu/stat/Cargo.toml b/src/uu/stat/Cargo.toml index f39f20c9a..26cc6b95e 100644 --- a/src/uu/stat/Cargo.toml +++ b/src/uu/stat/Cargo.toml @@ -17,8 +17,8 @@ path = "src/stat.rs" [dependencies] clap = "2.33" time = "0.1.40" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["entries", "libc"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["entries", "libc"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "stat" diff --git a/src/uu/stdbuf/Cargo.toml b/src/uu/stdbuf/Cargo.toml index 9da2e59c7..70fd32df1 100644 --- a/src/uu/stdbuf/Cargo.toml +++ b/src/uu/stdbuf/Cargo.toml @@ -17,8 +17,8 @@ path = "src/stdbuf.rs" [dependencies] getopts = "0.2.18" tempfile = "3.1" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [build-dependencies] libstdbuf = { version="0.0.1", package="uu_stdbuf_libstdbuf", path="src/libstdbuf" } diff --git a/src/uu/stdbuf/src/libstdbuf/Cargo.toml b/src/uu/stdbuf/src/libstdbuf/Cargo.toml index 0db28c1c4..878ea4450 100644 --- a/src/uu/stdbuf/src/libstdbuf/Cargo.toml +++ b/src/uu/stdbuf/src/libstdbuf/Cargo.toml @@ -19,8 +19,8 @@ crate-type = ["cdylib", "rlib"] # XXX: note: the rlib is just to prevent Cargo f [dependencies] cpp = "0.4" libc = "0.2" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../../../uucore_procs" } [build-dependencies] cpp_build = "0.4" diff --git a/src/uu/sum/Cargo.toml b/src/uu/sum/Cargo.toml index 2216e905e..54579d91c 100644 --- a/src/uu/sum/Cargo.toml +++ b/src/uu/sum/Cargo.toml @@ -16,8 +16,8 @@ path = "src/sum.rs" [dependencies] getopts = "0.2.18" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "sum" diff --git a/src/uu/sync/Cargo.toml b/src/uu/sync/Cargo.toml index d6dab2788..a5a18f770 100644 --- a/src/uu/sync/Cargo.toml +++ b/src/uu/sync/Cargo.toml @@ -15,10 +15,10 @@ edition = "2018" path = "src/sync.rs" [dependencies] -getopts = "0.2.18" +clap = "2.33" libc = "0.2.42" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["wide"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["wide"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } winapi = { version = "0.3", features = ["errhandlingapi", "fileapi", "handleapi", "std", "winbase", "winerror"] } [[bin]] diff --git a/src/uu/sync/src/sync.rs b/src/uu/sync/src/sync.rs index bb6d8cd80..c1b6cb8ad 100644 --- a/src/uu/sync/src/sync.rs +++ b/src/uu/sync/src/sync.rs @@ -7,17 +7,14 @@ /* Last synced with: sync (GNU coreutils) 8.13 */ -extern crate getopts; +extern crate clap; extern crate libc; -#[cfg(windows)] #[macro_use] extern crate uucore; -#[cfg(not(windows))] -extern crate uucore; - -static NAME: &str = "sync"; +use clap::App; +static ABOUT: &str = "Synchronize cached writes to persistent storage"; static VERSION: &str = env!("CARGO_PKG_VERSION"); #[cfg(unix)] @@ -118,57 +115,23 @@ mod platform { } } +fn get_usage() -> String { + format!("{0} [OPTION]... FILE...", executable!()) +} + pub fn uumain(args: impl uucore::Args) -> i32 { - let args = args.collect_str(); + let usage = get_usage(); - let mut opts = getopts::Options::new(); - - opts.optflag("h", "help", "display this help and exit"); - opts.optflag("V", "version", "output version information and exit"); - - let matches = match opts.parse(&args[1..]) { - Ok(m) => m, - _ => { - help(&opts); - return 1; - } - }; - - if matches.opt_present("h") { - help(&opts); - return 0; - } - - if matches.opt_present("V") { - version(); - return 0; - } + let _matches = App::new(executable!()) + .version(VERSION) + .about(ABOUT) + .usage(&usage[..]) + .get_matches_from(args); sync(); 0 } -fn version() { - println!("{} (uutils) {}", NAME, VERSION); - println!("The MIT License"); - println!(); - println!("Author -- Alexander Fomin."); -} - -fn help(opts: &getopts::Options) { - let msg = format!( - "{0} {1} - -Usage: - {0} [OPTION] - -Force changed blocks to disk, update the super block.", - NAME, VERSION - ); - - print!("{}", opts.usage(&msg)); -} - fn sync() -> isize { unsafe { platform::do_sync() } } diff --git a/src/uu/tac/Cargo.toml b/src/uu/tac/Cargo.toml index b5e3867ee..9cd7db989 100644 --- a/src/uu/tac/Cargo.toml +++ b/src/uu/tac/Cargo.toml @@ -16,8 +16,8 @@ path = "src/tac.rs" [dependencies] getopts = "0.2.18" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "tac" diff --git a/src/uu/tail/Cargo.toml b/src/uu/tail/Cargo.toml index a7cc75d7b..6eedd8e73 100644 --- a/src/uu/tail/Cargo.toml +++ b/src/uu/tail/Cargo.toml @@ -17,8 +17,8 @@ path = "src/tail.rs" [dependencies] getopts = "0.2.18" libc = "0.2.42" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } winapi = { version="0.3", features=["fileapi", "handleapi", "processthreadsapi", "synchapi", "winbase"] } [target.'cfg(target_os = "redox")'.dependencies] diff --git a/src/uu/tee/Cargo.toml b/src/uu/tee/Cargo.toml index 777b9a747..2712df686 100644 --- a/src/uu/tee/Cargo.toml +++ b/src/uu/tee/Cargo.toml @@ -17,8 +17,8 @@ path = "src/tee.rs" [dependencies] getopts = "0.2.18" libc = "0.2.42" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "tee" diff --git a/src/uu/test/Cargo.toml b/src/uu/test/Cargo.toml index 8cc621a63..120c513ba 100644 --- a/src/uu/test/Cargo.toml +++ b/src/uu/test/Cargo.toml @@ -16,8 +16,8 @@ path = "src/test.rs" [dependencies] libc = "0.2.42" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [target.'cfg(target_os = "redox")'.dependencies] redox_syscall = "0.1" diff --git a/src/uu/timeout/Cargo.toml b/src/uu/timeout/Cargo.toml index bc94a4d5a..f4a87d19d 100644 --- a/src/uu/timeout/Cargo.toml +++ b/src/uu/timeout/Cargo.toml @@ -18,8 +18,8 @@ path = "src/timeout.rs" getopts = "0.2.18" libc = "0.2.42" time = "0.1.40" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["parse_time", "process", "signals"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["parse_time", "process", "signals"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "timeout" diff --git a/src/uu/touch/Cargo.toml b/src/uu/touch/Cargo.toml index 7372c4347..5881875c1 100644 --- a/src/uu/touch/Cargo.toml +++ b/src/uu/touch/Cargo.toml @@ -18,8 +18,8 @@ path = "src/touch.rs" filetime = "0.2.1" getopts = "0.2.18" time = "0.1.40" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["libc"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["libc"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "touch" diff --git a/src/uu/tr/Cargo.toml b/src/uu/tr/Cargo.toml index 6f356cc65..364c8ea44 100644 --- a/src/uu/tr/Cargo.toml +++ b/src/uu/tr/Cargo.toml @@ -18,8 +18,8 @@ path = "src/tr.rs" bit-set = "0.5.0" fnv = "1.0.5" getopts = "0.2.18" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "tr" diff --git a/src/uu/true/Cargo.toml b/src/uu/true/Cargo.toml index a625e1c45..7c05520da 100644 --- a/src/uu/true/Cargo.toml +++ b/src/uu/true/Cargo.toml @@ -15,8 +15,8 @@ edition = "2018" path = "src/true.rs" [dependencies] -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "true" diff --git a/src/uu/truncate/Cargo.toml b/src/uu/truncate/Cargo.toml index 4da4b9487..9124c0bdf 100644 --- a/src/uu/truncate/Cargo.toml +++ b/src/uu/truncate/Cargo.toml @@ -16,8 +16,8 @@ path = "src/truncate.rs" [dependencies] clap = "2.33" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "truncate" diff --git a/src/uu/tsort/Cargo.toml b/src/uu/tsort/Cargo.toml index 74ea51a94..2c2dfcf42 100644 --- a/src/uu/tsort/Cargo.toml +++ b/src/uu/tsort/Cargo.toml @@ -16,8 +16,8 @@ path = "src/tsort.rs" [dependencies] getopts = "0.2.18" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "tsort" diff --git a/src/uu/tty/Cargo.toml b/src/uu/tty/Cargo.toml index ea521b431..d0cb0214c 100644 --- a/src/uu/tty/Cargo.toml +++ b/src/uu/tty/Cargo.toml @@ -17,8 +17,8 @@ path = "src/tty.rs" [dependencies] getopts = "0.2.18" libc = "0.2.42" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["fs"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["fs"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "tty" diff --git a/src/uu/uname/Cargo.toml b/src/uu/uname/Cargo.toml index fd0a7ca82..4eed217d0 100644 --- a/src/uu/uname/Cargo.toml +++ b/src/uu/uname/Cargo.toml @@ -17,8 +17,8 @@ path = "src/uname.rs" [dependencies] clap = "2.32" platform-info = "0.0.1" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "uname" diff --git a/src/uu/unexpand/Cargo.toml b/src/uu/unexpand/Cargo.toml index 933349a51..57b86f5cd 100644 --- a/src/uu/unexpand/Cargo.toml +++ b/src/uu/unexpand/Cargo.toml @@ -17,8 +17,8 @@ path = "src/unexpand.rs" [dependencies] getopts = "0.2.18" unicode-width = "0.1.5" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "unexpand" diff --git a/src/uu/uniq/Cargo.toml b/src/uu/uniq/Cargo.toml index 6de1088b5..0abdc3ac9 100644 --- a/src/uu/uniq/Cargo.toml +++ b/src/uu/uniq/Cargo.toml @@ -16,8 +16,8 @@ path = "src/uniq.rs" [dependencies] getopts = "0.2.18" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "uniq" diff --git a/src/uu/unlink/Cargo.toml b/src/uu/unlink/Cargo.toml index 5d13953b9..a4b84d999 100644 --- a/src/uu/unlink/Cargo.toml +++ b/src/uu/unlink/Cargo.toml @@ -17,8 +17,8 @@ path = "src/unlink.rs" [dependencies] getopts = "0.2.18" libc = "0.2.42" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "unlink" diff --git a/src/uu/uptime/Cargo.toml b/src/uu/uptime/Cargo.toml index 511dfd4b7..960db95f7 100644 --- a/src/uu/uptime/Cargo.toml +++ b/src/uu/uptime/Cargo.toml @@ -18,8 +18,8 @@ path = "src/uptime.rs" time = "0.1.40" chrono = "0.4" clap = "2.33" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["libc", "utmpx"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["libc", "utmpx"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "uptime" diff --git a/src/uu/users/Cargo.toml b/src/uu/users/Cargo.toml index ce9f9d212..e171ecd75 100644 --- a/src/uu/users/Cargo.toml +++ b/src/uu/users/Cargo.toml @@ -16,8 +16,8 @@ path = "src/users.rs" [dependencies] clap = "2.33" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["utmpx"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["utmpx"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "users" diff --git a/src/uu/wc/Cargo.toml b/src/uu/wc/Cargo.toml index b76a641a6..fe84d17f4 100644 --- a/src/uu/wc/Cargo.toml +++ b/src/uu/wc/Cargo.toml @@ -16,8 +16,8 @@ path = "src/wc.rs" [dependencies] clap = "2.33" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary" } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore" } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "wc" diff --git a/src/uu/who/Cargo.toml b/src/uu/who/Cargo.toml index 6b3646356..121299036 100644 --- a/src/uu/who/Cargo.toml +++ b/src/uu/who/Cargo.toml @@ -15,8 +15,8 @@ edition = "2018" path = "src/who.rs" [dependencies] -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["utmpx"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["utmpx"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [[bin]] name = "who" diff --git a/src/uu/whoami/Cargo.toml b/src/uu/whoami/Cargo.toml index ecda1ae2d..068eaa40a 100644 --- a/src/uu/whoami/Cargo.toml +++ b/src/uu/whoami/Cargo.toml @@ -17,8 +17,8 @@ path = "src/whoami.rs" [dependencies] advapi32-sys = "0.2.0" clap = "2.32" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["entries", "wide"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["entries", "wide"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } winapi = { version = "0.3", features = ["lmcons"] } [[bin]] diff --git a/src/uu/yes/Cargo.toml b/src/uu/yes/Cargo.toml index 1424a15ed..499baa67c 100644 --- a/src/uu/yes/Cargo.toml +++ b/src/uu/yes/Cargo.toml @@ -16,8 +16,8 @@ path = "src/yes.rs" [dependencies] clap = "2.32" -uucore = { version="0.0.4", package="uucore", git="https://github.com/uutils/uucore.git", branch="canary", features=["zero-copy"] } -uucore_procs = { version="0.0.4", package="uucore_procs", git="https://github.com/uutils/uucore.git", branch="canary" } +uucore = { version=">=0.0.4", package="uucore", path="../../uucore", features=["zero-copy"] } +uucore_procs = { version=">=0.0.4", package="uucore_procs", path="../../uucore_procs" } [features] default = [] diff --git a/src/uucore/Cargo.toml b/src/uucore/Cargo.toml new file mode 100644 index 000000000..db3b35004 --- /dev/null +++ b/src/uucore/Cargo.toml @@ -0,0 +1,51 @@ +[package] +name = "uucore" +version = "0.0.4" +authors = ["uutils developers"] +license = "MIT" +description = "uutils ~ 'core' uutils code library (cross-platform)" + +homepage = "https://github.com/uutils/coreutils" +repository = "https://github.com/uutils/coreutils/tree/master/src/uu/arch" +# readme = "README.md" +keywords = ["coreutils", "uutils", "cross-platform", "cli", "utility"] +categories = ["command-line-utilities"] +edition = "2018" + +[lib] +path="src/lib/lib.rs" + +[dependencies] +dunce = "1.0.0" +getopts = "<= 0.2.21" +wild = "2.0.4" +# * optional +failure = { version="<= 0.1.1", optional=true } +failure_derive = { version="<= 0.1.1", optional=true } +lazy_static = { version="1.3", optional=true } +nix = { version="<= 0.13", optional=true } +platform-info = { version="<= 0.0.1", optional=true } +time = { version="<= 0.1.42", optional=true } +# * "problem" dependencies (pinned) +data-encoding = { version="~2.1", optional=true } ## data-encoding: require v2.1; but v2.2.0 breaks the build for MinSRV v1.31.0 +libc = { version="0.2.15, <= 0.2.66", optional=true } ## libc: initial utmp support added in v0.2.15; but v0.2.68 breaks the build for MinSRV v1.31.0 +# * pinned transitive dependencies +pin_backtrace = { version=">= 0.3.3, <= 0.3.30", package="backtrace" } ## backtrace: transitive dependency via 'failure'; pin to <= v0.3.30 to avoid increasing MinSRV to v1.33.0 + +[target.'cfg(target_os = "redox")'.dependencies] +termion = "1.5" + +[features] +default = [] +# * non-default features +encoding = ["data-encoding", "failure", "failure_derive"] +entries = ["libc"] +fs = ["libc"] +mode = ["libc"] +parse_time = [] +process = ["libc"] +signals = [] +utf8 = [] +utmpx = ["time", "libc"] +wide = [] +zero-copy = ["nix", "libc", "lazy_static", "platform-info"] diff --git a/src/uucore/src/lib/features.rs b/src/uucore/src/lib/features.rs new file mode 100644 index 000000000..d5927fc6f --- /dev/null +++ b/src/uucore/src/lib/features.rs @@ -0,0 +1,32 @@ +// features ~ feature-gated modules (core/bundler file) + +#[cfg(feature = "encoding")] +pub mod encoding; +#[cfg(feature = "fs")] +pub mod fs; +#[cfg(feature = "parse_time")] +pub mod parse_time; +#[cfg(feature = "zero-copy")] +pub mod zero_copy; + +// * (platform-specific) feature-gated modules +// ** non-windows +#[cfg(all(not(windows), feature = "mode"))] +pub mod mode; +// ** unix-only +#[cfg(all(unix, feature = "entries"))] +pub mod entries; +#[cfg(all(unix, feature = "process"))] +pub mod process; +#[cfg(all(unix, not(target_os = "fuchsia"), feature = "signals"))] +pub mod signals; +#[cfg(all( + unix, + not(target_os = "fuchsia"), + not(target_env = "musl"), + feature = "utmpx" +))] +pub mod utmpx; +// ** windows-only +#[cfg(all(windows, feature = "wide"))] +pub mod wide; diff --git a/src/uucore/src/lib/features/encoding.rs b/src/uucore/src/lib/features/encoding.rs new file mode 100644 index 000000000..4bddd522e --- /dev/null +++ b/src/uucore/src/lib/features/encoding.rs @@ -0,0 +1,132 @@ +// This file is part of the uutils coreutils package. +// +// (c) Jian Zeng +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +// spell-checker:ignore (strings) ABCDEFGHIJKLMNOPQRSTUVWXYZ + +extern crate data_encoding; +extern crate failure; + +use self::data_encoding::{DecodeError, BASE32, BASE64}; + +use failure::Fail; +use std::io::{self, Read, Write}; + +#[derive(Fail, Debug)] +pub enum EncodingError { + #[fail(display = "{}", _0)] + Decode(#[cause] DecodeError), + #[fail(display = "{}", _0)] + Io(#[cause] io::Error), +} + +impl From for EncodingError { + fn from(err: io::Error) -> EncodingError { + EncodingError::Io(err) + } +} + +impl From for EncodingError { + fn from(err: DecodeError) -> EncodingError { + EncodingError::Decode(err) + } +} + +pub type DecodeResult = Result, EncodingError>; + +#[derive(Clone, Copy)] +pub enum Format { + Base32, + Base64, +} +use self::Format::*; + +pub fn encode(f: Format, input: &[u8]) -> String { + match f { + Base32 => BASE32.encode(input), + Base64 => BASE64.encode(input), + } +} + +pub fn decode(f: Format, input: &[u8]) -> DecodeResult { + Ok(match f { + Base32 => BASE32.decode(input)?, + Base64 => BASE64.decode(input)?, + }) +} + +pub struct Data { + line_wrap: usize, + ignore_garbage: bool, + input: R, + format: Format, + alphabet: &'static [u8], +} + +impl Data { + pub fn new(input: R, format: Format) -> Self { + Data { + line_wrap: 76, + ignore_garbage: false, + input, + format, + alphabet: match format { + Base32 => b"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=", + Base64 => b"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=+/", + }, + } + } + + pub fn line_wrap(mut self, wrap: usize) -> Self { + self.line_wrap = wrap; + self + } + + pub fn ignore_garbage(mut self, ignore: bool) -> Self { + self.ignore_garbage = ignore; + self + } + + pub fn decode(&mut self) -> DecodeResult { + let mut buf = vec![]; + self.input.read_to_end(&mut buf)?; + if self.ignore_garbage { + buf.retain(|c| self.alphabet.contains(c)); + } else { + buf.retain(|&c| c != b'\r' && c != b'\n'); + }; + decode(self.format, &buf) + } + + pub fn encode(&mut self) -> String { + let mut buf: Vec = vec![]; + self.input.read_to_end(&mut buf).unwrap(); + encode(self.format, buf.as_slice()) + } +} + +// NOTE: this will likely be phased out at some point +pub fn wrap_print(data: &Data, res: String) { + let stdout = io::stdout(); + wrap_write(stdout.lock(), data.line_wrap, res).unwrap(); +} + +pub fn wrap_write(mut writer: W, line_wrap: usize, res: String) -> io::Result<()> { + use std::cmp::min; + + if line_wrap == 0 { + return write!(writer, "{}", res); + } + + let mut start = 0; + while start < res.len() { + let end = min(start + line_wrap, res.len()); + writeln!(writer, "{}", &res[start..end])?; + start = end; + } + + Ok(()) +} diff --git a/src/uucore/src/lib/features/entries.rs b/src/uucore/src/lib/features/entries.rs new file mode 100644 index 000000000..a921af2d0 --- /dev/null +++ b/src/uucore/src/lib/features/entries.rs @@ -0,0 +1,270 @@ +// This file is part of the uutils coreutils package. +// +// (c) Jian Zeng +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +// spell-checker:ignore (vars) Passwd cstr fnam gecos ngroups + +//! Get password/group file entry +//! +//! # Examples: +//! +//! ``` +//! use uucore::entries::{self, Locate}; +//! +//! let root_group = if cfg!(any(target_os = "linux", target_os = "android")) { +//! "root" +//! } else { +//! "wheel" +//! }; +//! +//! assert_eq!("root", entries::uid2usr(0).unwrap()); +//! assert_eq!(0, entries::usr2uid("root").unwrap()); +//! assert!(entries::gid2grp(0).is_ok()); +//! assert!(entries::grp2gid(root_group).is_ok()); +//! +//! assert!(entries::Passwd::locate(0).is_ok()); +//! assert!(entries::Passwd::locate("0").is_ok()); +//! assert!(entries::Passwd::locate("root").is_ok()); +//! +//! assert!(entries::Group::locate(0).is_ok()); +//! assert!(entries::Group::locate("0").is_ok()); +//! assert!(entries::Group::locate(root_group).is_ok()); +//! ``` + +#[cfg(any(target_os = "freebsd", target_os = "macos"))] +use libc::time_t; +use libc::{c_char, c_int, gid_t, uid_t}; +use libc::{getgrgid, getgrnam, getgroups, getpwnam, getpwuid, group, passwd}; + +use std::borrow::Cow; +use std::ffi::{CStr, CString}; +use std::io::Error as IOError; +use std::io::ErrorKind; +use std::io::Result as IOResult; +use std::ptr; + +extern "C" { + fn getgrouplist( + name: *const c_char, + gid: gid_t, + groups: *mut gid_t, + ngroups: *mut c_int, + ) -> c_int; +} + +pub fn get_groups() -> IOResult> { + let ngroups = unsafe { getgroups(0, ptr::null_mut()) }; + if ngroups == -1 { + return Err(IOError::last_os_error()); + } + let mut groups = Vec::with_capacity(ngroups as usize); + let ngroups = unsafe { getgroups(ngroups, groups.as_mut_ptr()) }; + if ngroups == -1 { + Err(IOError::last_os_error()) + } else { + unsafe { + groups.set_len(ngroups as usize); + } + Ok(groups) + } +} + +pub struct Passwd { + inner: passwd, +} + +macro_rules! cstr2cow { + ($v:expr) => { + unsafe { CStr::from_ptr($v).to_string_lossy() } + }; +} + +impl Passwd { + /// AKA passwd.pw_name + pub fn name(&self) -> Cow { + cstr2cow!(self.inner.pw_name) + } + + /// AKA passwd.pw_uid + pub fn uid(&self) -> uid_t { + self.inner.pw_uid + } + + /// AKA passwd.pw_gid + pub fn gid(&self) -> gid_t { + self.inner.pw_gid + } + + /// AKA passwd.pw_gecos + pub fn user_info(&self) -> Cow { + cstr2cow!(self.inner.pw_gecos) + } + + /// AKA passwd.pw_shell + pub fn user_shell(&self) -> Cow { + cstr2cow!(self.inner.pw_shell) + } + + /// AKA passwd.pw_dir + pub fn user_dir(&self) -> Cow { + cstr2cow!(self.inner.pw_dir) + } + + /// AKA passwd.pw_passwd + pub fn user_passwd(&self) -> Cow { + cstr2cow!(self.inner.pw_passwd) + } + + /// AKA passwd.pw_class + #[cfg(any(target_os = "freebsd", target_os = "macos"))] + pub fn user_access_class(&self) -> Cow { + cstr2cow!(self.inner.pw_class) + } + + /// AKA passwd.pw_change + #[cfg(any(target_os = "freebsd", target_os = "macos"))] + pub fn passwd_change_time(&self) -> time_t { + self.inner.pw_change + } + + /// AKA passwd.pw_expire + #[cfg(any(target_os = "freebsd", target_os = "macos"))] + pub fn expiration(&self) -> time_t { + self.inner.pw_expire + } + + pub fn as_inner(&self) -> &passwd { + &self.inner + } + + pub fn into_inner(self) -> passwd { + self.inner + } + + pub fn belongs_to(&self) -> Vec { + let mut ngroups: c_int = 8; + let mut groups = Vec::with_capacity(ngroups as usize); + let gid = self.inner.pw_gid; + let name = self.inner.pw_name; + unsafe { + if getgrouplist(name, gid, groups.as_mut_ptr(), &mut ngroups) == -1 { + groups.resize(ngroups as usize, 0); + getgrouplist(name, gid, groups.as_mut_ptr(), &mut ngroups); + } + groups.set_len(ngroups as usize); + } + groups.truncate(ngroups as usize); + groups + } +} + +pub struct Group { + inner: group, +} + +impl Group { + /// AKA group.gr_name + pub fn name(&self) -> Cow { + cstr2cow!(self.inner.gr_name) + } + + /// AKA group.gr_gid + pub fn gid(&self) -> gid_t { + self.inner.gr_gid + } + + pub fn as_inner(&self) -> &group { + &self.inner + } + + pub fn into_inner(self) -> group { + self.inner + } +} + +/// Fetch desired entry. +pub trait Locate { + fn locate(key: K) -> IOResult + where + Self: ::std::marker::Sized; +} + +macro_rules! f { + ($fnam:ident, $fid:ident, $t:ident, $st:ident) => { + impl Locate<$t> for $st { + fn locate(k: $t) -> IOResult { + unsafe { + let data = $fid(k); + if !data.is_null() { + Ok($st { + inner: ptr::read(data as *const _), + }) + } else { + Err(IOError::new( + ErrorKind::NotFound, + format!("No such id: {}", k), + )) + } + } + } + } + + impl<'a> Locate<&'a str> for $st { + fn locate(k: &'a str) -> IOResult { + if let Ok(id) = k.parse::<$t>() { + let data = unsafe { $fid(id) }; + if !data.is_null() { + Ok($st { + inner: unsafe { ptr::read(data as *const _) }, + }) + } else { + Err(IOError::new( + ErrorKind::NotFound, + format!("No such id: {}", id), + )) + } + } else { + unsafe { + let data = $fnam(CString::new(k).unwrap().as_ptr()); + if !data.is_null() { + Ok($st { + inner: ptr::read(data as *const _), + }) + } else { + Err(IOError::new( + ErrorKind::NotFound, + format!("Not found: {}", k), + )) + } + } + } + } + } + }; +} + +f!(getpwnam, getpwuid, uid_t, Passwd); +f!(getgrnam, getgrgid, gid_t, Group); + +#[inline] +pub fn uid2usr(id: uid_t) -> IOResult { + Passwd::locate(id).map(|p| p.name().into_owned()) +} + +#[inline] +pub fn gid2grp(id: gid_t) -> IOResult { + Group::locate(id).map(|p| p.name().into_owned()) +} + +#[inline] +pub fn usr2uid(name: &str) -> IOResult { + Passwd::locate(name).map(|p| p.uid()) +} + +#[inline] +pub fn grp2gid(name: &str) -> IOResult { + Group::locate(name).map(|p| p.gid()) +} diff --git a/src/uucore/src/lib/features/fs.rs b/src/uucore/src/lib/features/fs.rs new file mode 100644 index 000000000..6fda8460a --- /dev/null +++ b/src/uucore/src/lib/features/fs.rs @@ -0,0 +1,273 @@ +// This file is part of the uutils coreutils package. +// +// (c) Joseph Crail +// (c) Jian Zeng +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +#[cfg(windows)] +extern crate dunce; +#[cfg(target_os = "redox")] +extern crate termion; + +#[cfg(unix)] +use libc::{ + mode_t, S_IRGRP, S_IROTH, S_IRUSR, S_ISGID, S_ISUID, S_ISVTX, S_IWGRP, S_IWOTH, S_IWUSR, + S_IXGRP, S_IXOTH, S_IXUSR, +}; +use std::borrow::Cow; +use std::env; +use std::fs; +#[cfg(target_os = "redox")] +use std::io; +use std::io::Result as IOResult; +use std::io::{Error, ErrorKind}; +#[cfg(any(unix, target_os = "redox"))] +use std::os::unix::fs::MetadataExt; +use std::path::{Component, Path, PathBuf}; + +#[cfg(unix)] +macro_rules! has { + ($mode:expr, $perm:expr) => { + $mode & ($perm as u32) != 0 + }; +} + +pub fn resolve_relative_path(path: &Path) -> Cow { + if path.components().all(|e| e != Component::ParentDir) { + return path.into(); + } + let root = Component::RootDir.as_os_str(); + let mut result = env::current_dir().unwrap_or_else(|_| PathBuf::from(root)); + for comp in path.components() { + match comp { + Component::ParentDir => { + if let Ok(p) = result.read_link() { + result = p; + } + result.pop(); + } + Component::CurDir => (), + Component::RootDir | Component::Normal(_) | Component::Prefix(_) => { + result.push(comp.as_os_str()) + } + } + } + result.into() +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum CanonicalizeMode { + None, + Normal, + Existing, + Missing, +} + +fn resolve>(original: P) -> IOResult { + const MAX_LINKS_FOLLOWED: u32 = 255; + let mut followed = 0; + let mut result = original.as_ref().to_path_buf(); + loop { + if followed == MAX_LINKS_FOLLOWED { + return Err(Error::new( + ErrorKind::InvalidInput, + "maximum links followed", + )); + } + + match fs::symlink_metadata(&result) { + Err(e) => return Err(e), + Ok(ref m) if !m.file_type().is_symlink() => break, + Ok(..) => { + followed += 1; + match fs::read_link(&result) { + Ok(path) => { + result.pop(); + result.push(path); + } + Err(e) => { + return Err(e); + } + } + } + } + } + Ok(result) +} + +pub fn canonicalize>(original: P, can_mode: CanonicalizeMode) -> IOResult { + // Create an absolute path + let original = original.as_ref(); + let original = if original.is_absolute() { + original.to_path_buf() + } else { + dunce::canonicalize(env::current_dir().unwrap()) + .unwrap() + .join(original) + }; + + let mut result = PathBuf::new(); + let mut parts = vec![]; + + // Split path by directory separator; add prefix (Windows-only) and root + // directory to final path buffer; add remaining parts to temporary + // vector for canonicalization. + for part in original.components() { + match part { + Component::Prefix(_) | Component::RootDir => { + result.push(part.as_os_str()); + } + Component::CurDir => (), + Component::ParentDir => { + parts.pop(); + } + Component::Normal(_) => { + parts.push(part.as_os_str()); + } + } + } + + // Resolve the symlinks where possible + if !parts.is_empty() { + for part in parts[..parts.len() - 1].iter() { + result.push(part); + + if can_mode == CanonicalizeMode::None { + continue; + } + + match resolve(&result) { + Err(e) => match can_mode { + CanonicalizeMode::Missing => continue, + _ => return Err(e), + }, + Ok(path) => { + result.pop(); + result.push(path); + } + } + } + + result.push(parts.last().unwrap()); + + match resolve(&result) { + Err(e) => { + if can_mode == CanonicalizeMode::Existing { + return Err(e); + } + } + Ok(path) => { + result.pop(); + result.push(path); + } + } + } + Ok(result) +} + +#[cfg(unix)] +pub fn is_stdin_interactive() -> bool { + unsafe { libc::isatty(libc::STDIN_FILENO) == 1 } +} + +#[cfg(windows)] +pub fn is_stdin_interactive() -> bool { + false +} + +#[cfg(target_os = "redox")] +pub fn is_stdin_interactive() -> bool { + termion::is_tty(&io::stdin()) +} + +#[cfg(unix)] +pub fn is_stdout_interactive() -> bool { + unsafe { libc::isatty(libc::STDOUT_FILENO) == 1 } +} + +#[cfg(windows)] +pub fn is_stdout_interactive() -> bool { + false +} + +#[cfg(target_os = "redox")] +pub fn is_stdout_interactive() -> bool { + termion::is_tty(&io::stdout()) +} + +#[cfg(unix)] +pub fn is_stderr_interactive() -> bool { + unsafe { libc::isatty(libc::STDERR_FILENO) == 1 } +} + +#[cfg(windows)] +pub fn is_stderr_interactive() -> bool { + false +} + +#[cfg(target_os = "redox")] +pub fn is_stderr_interactive() -> bool { + termion::is_tty(&io::stderr()) +} + +#[cfg(not(unix))] +#[allow(unused_variables)] +pub fn display_permissions(metadata: &fs::Metadata) -> String { + String::from("---------") +} + +#[cfg(unix)] +pub fn display_permissions(metadata: &fs::Metadata) -> String { + let mode: mode_t = metadata.mode() as mode_t; + display_permissions_unix(mode as u32) +} + +#[cfg(unix)] +pub fn display_permissions_unix(mode: u32) -> String { + let mut result = String::with_capacity(9); + result.push(if has!(mode, S_IRUSR) { 'r' } else { '-' }); + result.push(if has!(mode, S_IWUSR) { 'w' } else { '-' }); + result.push(if has!(mode, S_ISUID) { + if has!(mode, S_IXUSR) { + 's' + } else { + 'S' + } + } else if has!(mode, S_IXUSR) { + 'x' + } else { + '-' + }); + + result.push(if has!(mode, S_IRGRP) { 'r' } else { '-' }); + result.push(if has!(mode, S_IWGRP) { 'w' } else { '-' }); + result.push(if has!(mode, S_ISGID) { + if has!(mode, S_IXGRP) { + 's' + } else { + 'S' + } + } else if has!(mode, S_IXGRP) { + 'x' + } else { + '-' + }); + + result.push(if has!(mode, S_IROTH) { 'r' } else { '-' }); + result.push(if has!(mode, S_IWOTH) { 'w' } else { '-' }); + result.push(if has!(mode, S_ISVTX) { + if has!(mode, S_IXOTH) { + 't' + } else { + 'T' + } + } else if has!(mode, S_IXOTH) { + 'x' + } else { + '-' + }); + + result +} diff --git a/src/uucore/src/lib/features/mode.rs b/src/uucore/src/lib/features/mode.rs new file mode 100644 index 000000000..50679d107 --- /dev/null +++ b/src/uucore/src/lib/features/mode.rs @@ -0,0 +1,131 @@ +// This file is part of the uutils coreutils package. +// +// (c) Alex Lyon +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +// spell-checker:ignore (vars) fperm srwx + +pub fn parse_numeric(fperm: u32, mut mode: &str) -> Result { + let (op, pos) = parse_op(mode, Some('='))?; + mode = mode[pos..].trim_start_matches('0'); + if mode.len() > 4 { + Err(format!("mode is too large ({} > 7777)", mode)) + } else { + match u32::from_str_radix(mode, 8) { + Ok(change) => Ok(match op { + '+' => fperm | change, + '-' => fperm & !change, + '=' => change, + _ => unreachable!(), + }), + Err(err) => Err(err.to_string()), + } + } +} + +pub fn parse_symbolic( + mut fperm: u32, + mut mode: &str, + considering_dir: bool, +) -> Result { + #[cfg(unix)] + use libc::umask; + + #[cfg(target_os = "redox")] + unsafe fn umask(_mask: u32) -> u32 { + // XXX Redox does not currently have umask + 0 + } + + let (mask, pos) = parse_levels(mode); + if pos == mode.len() { + return Err(format!("invalid mode ({})", mode)); + } + let respect_umask = pos == 0; + let last_umask = unsafe { umask(0) }; + mode = &mode[pos..]; + while !mode.is_empty() { + let (op, pos) = parse_op(mode, None)?; + mode = &mode[pos..]; + let (mut srwx, pos) = parse_change(mode, fperm, considering_dir); + if respect_umask { + srwx &= !(last_umask as u32); + } + mode = &mode[pos..]; + match op { + '+' => fperm |= srwx & mask, + '-' => fperm &= !(srwx & mask), + '=' => fperm = (fperm & !mask) | (srwx & mask), + _ => unreachable!(), + } + } + unsafe { + umask(last_umask); + } + Ok(fperm) +} + +fn parse_levels(mode: &str) -> (u32, usize) { + let mut mask = 0; + let mut pos = 0; + for ch in mode.chars() { + mask |= match ch { + 'u' => 0o7700, + 'g' => 0o7070, + 'o' => 0o7007, + 'a' => 0o7777, + _ => break, + }; + pos += 1; + } + if pos == 0 { + mask = 0o7777; // default to 'a' + } + (mask, pos) +} + +fn parse_op(mode: &str, default: Option) -> Result<(char, usize), String> { + match mode.chars().next() { + Some(ch) => match ch { + '+' | '-' | '=' => Ok((ch, 1)), + _ => match default { + Some(ch) => Ok((ch, 0)), + None => Err(format!( + "invalid operator (expected +, -, or =, but found {})", + ch + )), + }, + }, + None => Err("unexpected end of mode".to_owned()), + } +} + +fn parse_change(mode: &str, fperm: u32, considering_dir: bool) -> (u32, usize) { + let mut srwx = fperm & 0o7000; + let mut pos = 0; + for ch in mode.chars() { + match ch { + 'r' => srwx |= 0o444, + 'w' => srwx |= 0o222, + 'x' => srwx |= 0o111, + 'X' => { + if considering_dir || (fperm & 0o0111) != 0 { + srwx |= 0o111 + } + } + 's' => srwx |= 0o4000 | 0o2000, + 't' => srwx |= 0o1000, + 'u' => srwx = (fperm & 0o700) | ((fperm >> 3) & 0o070) | ((fperm >> 6) & 0o007), + 'g' => srwx = ((fperm << 3) & 0o700) | (fperm & 0o070) | ((fperm >> 3) & 0o007), + 'o' => srwx = ((fperm << 6) & 0o700) | ((fperm << 3) & 0o070) | (fperm & 0o007), + _ => break, + }; + pos += 1; + } + if pos == 0 { + srwx = 0; + } + (srwx, pos) +} diff --git a/src/uucore/src/lib/features/parse_time.rs b/src/uucore/src/lib/features/parse_time.rs new file mode 100644 index 000000000..8e822685b --- /dev/null +++ b/src/uucore/src/lib/features/parse_time.rs @@ -0,0 +1,43 @@ +// This file is part of the uutils coreutils package. +// +// (c) Alex Lyon +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +// spell-checker:ignore (vars) NANOS numstr + +use std::time::Duration; + +pub fn from_str(string: &str) -> Result { + let len = string.len(); + if len == 0 { + return Err("empty string".to_owned()); + } + let slice = &string[..len - 1]; + let (numstr, times) = match string.chars().next_back().unwrap() { + 's' | 'S' => (slice, 1), + 'm' | 'M' => (slice, 60), + 'h' | 'H' => (slice, 60 * 60), + 'd' | 'D' => (slice, 60 * 60 * 24), + val => { + if !val.is_alphabetic() { + (string, 1) + } else if string == "inf" || string == "infinity" { + ("inf", 1) + } else { + return Err(format!("invalid time interval '{}'", string)); + } + } + }; + let num = match numstr.parse::() { + Ok(m) => m, + Err(e) => return Err(format!("invalid time interval '{}': {}", string, e)), + }; + + const NANOS_PER_SEC: u32 = 1_000_000_000; + let whole_secs = num.trunc(); + let nanos = (num.fract() * (NANOS_PER_SEC as f64)).trunc(); + let duration = Duration::new(whole_secs as u64, nanos as u32); + Ok(duration * times) +} diff --git a/src/uucore/src/lib/features/process.rs b/src/uucore/src/lib/features/process.rs new file mode 100644 index 000000000..f3f9680e8 --- /dev/null +++ b/src/uucore/src/lib/features/process.rs @@ -0,0 +1,146 @@ +// This file is part of the uutils coreutils package. +// +// (c) Maciej Dziardziel +// (c) Jian Zeng +// +// For the full copyright and license information, please view the LICENSE file +// that was distributed with this source code. + +// spell-checker:ignore (vars) cvar exitstatus +// spell-checker:ignore (sys/unix) WIFSIGNALED + +use libc::{c_int, gid_t, pid_t, uid_t}; +use std::fmt; +use std::io; +use std::process::Child; +use std::sync::{Arc, Condvar, Mutex}; +use std::thread; +use std::time::{Duration, Instant}; + +pub fn geteuid() -> uid_t { + unsafe { libc::geteuid() } +} + +pub fn getegid() -> gid_t { + unsafe { libc::getegid() } +} + +pub fn getgid() -> gid_t { + unsafe { libc::getgid() } +} + +pub fn getuid() -> uid_t { + unsafe { libc::getuid() } +} + +// This is basically sys::unix::process::ExitStatus +#[derive(PartialEq, Eq, Clone, Copy, Debug)] +pub enum ExitStatus { + Code(i32), + Signal(i32), +} + +impl ExitStatus { + fn from_status(status: c_int) -> ExitStatus { + if status & 0x7F != 0 { + // WIFSIGNALED(status) == terminating by/with unhandled signal + ExitStatus::Signal(status & 0x7F) + } else { + ExitStatus::Code(status & 0xFF00 >> 8) + } + } + + pub fn success(&self) -> bool { + match *self { + ExitStatus::Code(code) => code == 0, + _ => false, + } + } + + pub fn code(&self) -> Option { + match *self { + ExitStatus::Code(code) => Some(code), + _ => None, + } + } + + pub fn signal(&self) -> Option { + match *self { + ExitStatus::Signal(code) => Some(code), + _ => None, + } + } +} + +impl fmt::Display for ExitStatus { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + ExitStatus::Code(code) => write!(f, "exit code: {}", code), + ExitStatus::Signal(code) => write!(f, "exit code: {}", code), + } + } +} + +/// Missing methods for Child objects +pub trait ChildExt { + /// Send a signal to a Child process. + fn send_signal(&mut self, signal: usize) -> io::Result<()>; + + /// Wait for a process to finish or return after the specified duration. + fn wait_or_timeout(&mut self, timeout: Duration) -> io::Result>; +} + +impl ChildExt for Child { + fn send_signal(&mut self, signal: usize) -> io::Result<()> { + if unsafe { libc::kill(self.id() as pid_t, signal as i32) } != 0 { + Err(io::Error::last_os_error()) + } else { + Ok(()) + } + } + + fn wait_or_timeout(&mut self, timeout: Duration) -> io::Result> { + // The result will be written to that Option, protected by a Mutex + // Then the Condvar will be signaled + let state = Arc::new(( + Mutex::new(Option::None::>), + Condvar::new(), + )); + + // Start the waiting thread + let state_th = state.clone(); + let pid_th = self.id(); + thread::spawn(move || { + let &(ref lock_th, ref cvar_th) = &*state_th; + // Child::wait() would need a &mut to self, can't use that... + // use waitpid() directly, with our own ExitStatus + let mut status: c_int = 0; + let r = unsafe { libc::waitpid(pid_th as i32, &mut status, 0) }; + // Fill the Option and notify on the Condvar + let mut exitstatus_th = lock_th.lock().unwrap(); + if r != pid_th as c_int { + *exitstatus_th = Some(Err(io::Error::last_os_error())); + } else { + let s = ExitStatus::from_status(status); + *exitstatus_th = Some(Ok(s)); + } + cvar_th.notify_one(); + }); + + // Main thread waits + let &(ref lock, ref cvar) = &*state; + let mut exitstatus = lock.lock().unwrap(); + // Condvar::wait_timeout_ms() can wake too soon, in this case wait again + let start = Instant::now(); + loop { + if let Some(exitstatus) = exitstatus.take() { + return exitstatus.map(Some); + } + if start.elapsed() >= timeout { + return Ok(None); + } + let cvar_timeout = timeout - start.elapsed(); + exitstatus = cvar.wait_timeout(exitstatus, cvar_timeout).unwrap().0; + } + } +} diff --git a/src/uucore/src/lib/features/signals.rs b/src/uucore/src/lib/features/signals.rs new file mode 100644 index 000000000..294669eab --- /dev/null +++ b/src/uucore/src/lib/features/signals.rs @@ -0,0 +1,390 @@ +// This file is part of the uutils coreutils package. +// +// (c) Maciej Dziardziel +// +// For the full copyright and license information, please view the LICENSE file +// that was distributed with this source code. + +// spell-checker:ignore (vars/api) fcntl setrlimit setitimer +// spell-checker:ignore (vars/signals) ABRT ALRM CHLD SEGV SIGABRT SIGALRM SIGBUS SIGCHLD SIGCONT SIGEMT SIGFPE SIGHUP SIGILL SIGINFO SIGINT SIGIO SIGIOT SIGKILL SIGPIPE SIGPROF SIGQUIT SIGSEGV SIGSTOP SIGSYS SIGTERM SIGTRAP SIGTSTP SIGTTIN SIGTTOU SIGURG SIGUSR SIGVTALRM SIGWINCH SIGXCPU SIGXFSZ STKFLT TSTP TTIN TTOU VTALRM XCPU XFSZ + +pub static DEFAULT_SIGNAL: usize = 15; + +pub struct Signal<'a> { + pub name: &'a str, + pub value: usize, +} + +/* + +Linux Programmer's Manual + + 1 HUP 2 INT 3 QUIT 4 ILL 5 TRAP 6 ABRT 7 BUS + 8 FPE 9 KILL 10 USR1 11 SEGV 12 USR2 13 PIPE 14 ALRM +15 TERM 16 STKFLT 17 CHLD 18 CONT 19 STOP 20 TSTP 21 TTIN +22 TTOU 23 URG 24 XCPU 25 XFSZ 26 VTALRM 27 PROF 28 WINCH +29 POLL 30 PWR 31 SYS + + +*/ + +#[cfg(target_os = "linux")] +pub static ALL_SIGNALS: [Signal<'static>; 31] = [ + Signal { + name: "HUP", + value: 1, + }, + Signal { + name: "INT", + value: 2, + }, + Signal { + name: "QUIT", + value: 3, + }, + Signal { + name: "ILL", + value: 4, + }, + Signal { + name: "TRAP", + value: 5, + }, + Signal { + name: "ABRT", + value: 6, + }, + Signal { + name: "BUS", + value: 7, + }, + Signal { + name: "FPE", + value: 8, + }, + Signal { + name: "KILL", + value: 9, + }, + Signal { + name: "USR1", + value: 10, + }, + Signal { + name: "SEGV", + value: 11, + }, + Signal { + name: "USR2", + value: 12, + }, + Signal { + name: "PIPE", + value: 13, + }, + Signal { + name: "ALRM", + value: 14, + }, + Signal { + name: "TERM", + value: 15, + }, + Signal { + name: "STKFLT", + value: 16, + }, + Signal { + name: "CHLD", + value: 17, + }, + Signal { + name: "CONT", + value: 18, + }, + Signal { + name: "STOP", + value: 19, + }, + Signal { + name: "TSTP", + value: 20, + }, + Signal { + name: "TTIN", + value: 21, + }, + Signal { + name: "TTOU", + value: 22, + }, + Signal { + name: "URG", + value: 23, + }, + Signal { + name: "XCPU", + value: 24, + }, + Signal { + name: "XFSZ", + value: 25, + }, + Signal { + name: "VTALRM", + value: 26, + }, + Signal { + name: "PROF", + value: 27, + }, + Signal { + name: "WINCH", + value: 28, + }, + Signal { + name: "POLL", + value: 29, + }, + Signal { + name: "PWR", + value: 30, + }, + Signal { + name: "SYS", + value: 31, + }, +]; + +/* + + +https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/signal.3.html + + +No Name Default Action Description +1 SIGHUP terminate process terminal line hangup +2 SIGINT terminate process interrupt program +3 SIGQUIT create core image quit program +4 SIGILL create core image illegal instruction +5 SIGTRAP create core image trace trap +6 SIGABRT create core image abort program (formerly SIGIOT) +7 SIGEMT create core image emulate instruction executed +8 SIGFPE create core image floating-point exception +9 SIGKILL terminate process kill program +10 SIGBUS create core image bus error +11 SIGSEGV create core image segmentation violation +12 SIGSYS create core image non-existent system call invoked +13 SIGPIPE terminate process write on a pipe with no reader +14 SIGALRM terminate process real-time timer expired +15 SIGTERM terminate process software termination signal +16 SIGURG discard signal urgent condition present on socket +17 SIGSTOP stop process stop (cannot be caught or ignored) +18 SIGTSTP stop process stop signal generated from keyboard +19 SIGCONT discard signal continue after stop +20 SIGCHLD discard signal child status has changed +21 SIGTTIN stop process background read attempted from control terminal +22 SIGTTOU stop process background write attempted to control terminal +23 SIGIO discard signal I/O is possible on a descriptor (see fcntl(2)) +24 SIGXCPU terminate process cpu time limit exceeded (see setrlimit(2)) +25 SIGXFSZ terminate process file size limit exceeded (see setrlimit(2)) +26 SIGVTALRM terminate process virtual time alarm (see setitimer(2)) +27 SIGPROF terminate process profiling timer alarm (see setitimer(2)) +28 SIGWINCH discard signal Window size change +29 SIGINFO discard signal status request from keyboard +30 SIGUSR1 terminate process User defined signal 1 +31 SIGUSR2 terminate process User defined signal 2 + +*/ + +#[cfg(any(target_os = "macos", target_os = "freebsd"))] +pub static ALL_SIGNALS: [Signal<'static>; 31] = [ + Signal { + name: "HUP", + value: 1, + }, + Signal { + name: "INT", + value: 2, + }, + Signal { + name: "QUIT", + value: 3, + }, + Signal { + name: "ILL", + value: 4, + }, + Signal { + name: "TRAP", + value: 5, + }, + Signal { + name: "ABRT", + value: 6, + }, + Signal { + name: "EMT", + value: 7, + }, + Signal { + name: "FPE", + value: 8, + }, + Signal { + name: "KILL", + value: 9, + }, + Signal { + name: "BUS", + value: 10, + }, + Signal { + name: "SEGV", + value: 11, + }, + Signal { + name: "SYS", + value: 12, + }, + Signal { + name: "PIPE", + value: 13, + }, + Signal { + name: "ALRM", + value: 14, + }, + Signal { + name: "TERM", + value: 15, + }, + Signal { + name: "URG", + value: 16, + }, + Signal { + name: "STOP", + value: 17, + }, + Signal { + name: "TSTP", + value: 18, + }, + Signal { + name: "CONT", + value: 19, + }, + Signal { + name: "CHLD", + value: 20, + }, + Signal { + name: "TTIN", + value: 21, + }, + Signal { + name: "TTOU", + value: 22, + }, + Signal { + name: "IO", + value: 23, + }, + Signal { + name: "XCPU", + value: 24, + }, + Signal { + name: "XFSZ", + value: 25, + }, + Signal { + name: "VTALRM", + value: 26, + }, + Signal { + name: "PROF", + value: 27, + }, + Signal { + name: "WINCH", + value: 28, + }, + Signal { + name: "INFO", + value: 29, + }, + Signal { + name: "USR1", + value: 30, + }, + Signal { + name: "USR2", + value: 31, + }, +]; + +pub fn signal_by_name_or_value(signal_name_or_value: &str) -> Option { + if let Ok(value) = signal_name_or_value.parse() { + if is_signal(value) { + return Some(value); + } else { + return None; + } + } + let signal_name = signal_name_or_value.trim_start_matches("SIG"); + + ALL_SIGNALS + .iter() + .find(|s| s.name == signal_name) + .map(|s| s.value) +} + +#[inline(always)] +pub fn is_signal(num: usize) -> bool { + // Named signals start at 1 + num <= ALL_SIGNALS.len() +} + +#[test] +fn signals_all_contiguous() { + for (i, signal) in ALL_SIGNALS.iter().enumerate() { + assert_eq!(signal.value, i + 1); + } +} + +#[test] +fn signals_all_are_signal() { + for signal in &ALL_SIGNALS { + assert!(is_signal(signal.value)); + } +} + +#[test] +fn signal_by_value() { + assert_eq!(signal_by_name_or_value("0"), Some(0)); + for signal in &ALL_SIGNALS { + assert_eq!( + signal_by_name_or_value(&signal.value.to_string()), + Some(signal.value) + ); + } +} + +#[test] +fn signal_by_short_name() { + for signal in &ALL_SIGNALS { + assert_eq!(signal_by_name_or_value(signal.name), Some(signal.value)); + } +} + +#[test] +fn signal_by_long_name() { + for signal in &ALL_SIGNALS { + assert_eq!( + signal_by_name_or_value(&format!("SIG{}", signal.name)), + Some(signal.value) + ); + } +} diff --git a/src/uucore/src/lib/features/utmpx.rs b/src/uucore/src/lib/features/utmpx.rs new file mode 100644 index 000000000..ab3de65fa --- /dev/null +++ b/src/uucore/src/lib/features/utmpx.rs @@ -0,0 +1,273 @@ +// This file is part of the uutils coreutils package. +// +// (c) Jian Zeng +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. +// +//! Aims to provide platform-independent methods to obtain login records +//! +//! **ONLY** support linux, macos and freebsd for the time being +//! +//! # Examples: +//! +//! ``` +//! use uucore::utmpx::Utmpx; +//! for ut in Utmpx::iter_all_records() { +//! if ut.is_user_process() { +//! println!("{}: {}", ut.host(), ut.user()) +//! } +//! } +//! ``` +//! +//! Specifying the path to login record: +//! +//! ``` +//! use uucore::utmpx::Utmpx; +//! for ut in Utmpx::iter_all_records().read_from("/some/where/else") { +//! if ut.is_user_process() { +//! println!("{}: {}", ut.host(), ut.user()) +//! } +//! } +//! ``` + +pub extern crate time; +use self::time::{Timespec, Tm}; + +use std::ffi::CString; +use std::io::Error as IOError; +use std::io::Result as IOResult; +use std::ptr; + +pub use self::ut::*; +use libc::utmpx; +// pub use libc::getutxid; +// pub use libc::getutxline; +// pub use libc::pututxline; +pub use libc::endutxent; +pub use libc::getutxent; +pub use libc::setutxent; +#[cfg(any(target_os = "macos", target_os = "linux"))] +pub use libc::utmpxname; +#[cfg(target_os = "freebsd")] +pub unsafe extern "C" fn utmpxname(_file: *const libc::c_char) -> libc::c_int { + 0 +} + +// In case the c_char array doesn't end with NULL +macro_rules! chars2string { + ($arr:expr) => { + $arr.iter() + .take_while(|i| **i > 0) + .map(|&i| i as u8 as char) + .collect::() + }; +} + +#[cfg(target_os = "linux")] +mod ut { + pub static DEFAULT_FILE: &str = "/var/run/utmp"; + + pub use libc::__UT_HOSTSIZE as UT_HOSTSIZE; + pub use libc::__UT_LINESIZE as UT_LINESIZE; + pub use libc::__UT_NAMESIZE as UT_NAMESIZE; + pub const UT_IDSIZE: usize = 4; + + pub use libc::ACCOUNTING; + pub use libc::BOOT_TIME; + pub use libc::DEAD_PROCESS; + pub use libc::EMPTY; + pub use libc::INIT_PROCESS; + pub use libc::LOGIN_PROCESS; + pub use libc::NEW_TIME; + pub use libc::OLD_TIME; + pub use libc::RUN_LVL; + pub use libc::USER_PROCESS; +} + +#[cfg(target_os = "macos")] +mod ut { + pub static DEFAULT_FILE: &str = "/var/run/utmpx"; + + pub use libc::_UTX_HOSTSIZE as UT_HOSTSIZE; + pub use libc::_UTX_IDSIZE as UT_IDSIZE; + pub use libc::_UTX_LINESIZE as UT_LINESIZE; + pub use libc::_UTX_USERSIZE as UT_NAMESIZE; + + pub use libc::ACCOUNTING; + pub use libc::BOOT_TIME; + pub use libc::DEAD_PROCESS; + pub use libc::EMPTY; + pub use libc::INIT_PROCESS; + pub use libc::LOGIN_PROCESS; + pub use libc::NEW_TIME; + pub use libc::OLD_TIME; + pub use libc::RUN_LVL; + pub use libc::SHUTDOWN_TIME; + pub use libc::SIGNATURE; + pub use libc::USER_PROCESS; +} + +#[cfg(target_os = "freebsd")] +mod ut { + pub static DEFAULT_FILE: &str = ""; + + pub const UT_LINESIZE: usize = 16; + pub const UT_NAMESIZE: usize = 32; + pub const UT_IDSIZE: usize = 8; + pub const UT_HOSTSIZE: usize = 128; + + pub use libc::BOOT_TIME; + pub use libc::DEAD_PROCESS; + pub use libc::EMPTY; + pub use libc::INIT_PROCESS; + pub use libc::LOGIN_PROCESS; + pub use libc::NEW_TIME; + pub use libc::OLD_TIME; + pub use libc::SHUTDOWN_TIME; + pub use libc::USER_PROCESS; +} + +pub struct Utmpx { + inner: utmpx, +} + +impl Utmpx { + /// A.K.A. ut.ut_type + pub fn record_type(&self) -> i16 { + self.inner.ut_type as i16 + } + /// A.K.A. ut.ut_pid + pub fn pid(&self) -> i32 { + self.inner.ut_pid as i32 + } + /// A.K.A. ut.ut_id + pub fn terminal_suffix(&self) -> String { + chars2string!(self.inner.ut_id) + } + /// A.K.A. ut.ut_user + pub fn user(&self) -> String { + chars2string!(self.inner.ut_user) + } + /// A.K.A. ut.ut_host + pub fn host(&self) -> String { + chars2string!(self.inner.ut_host) + } + /// A.K.A. ut.ut_line + pub fn tty_device(&self) -> String { + chars2string!(self.inner.ut_line) + } + /// A.K.A. ut.ut_tv + pub fn login_time(&self) -> Tm { + time::at(Timespec::new( + self.inner.ut_tv.tv_sec as i64, + self.inner.ut_tv.tv_usec as i32, + )) + } + /// A.K.A. ut.ut_exit + /// + /// Return (e_termination, e_exit) + #[cfg(any(target_os = "linux", target_os = "android"))] + pub fn exit_status(&self) -> (i16, i16) { + (self.inner.ut_exit.e_termination, self.inner.ut_exit.e_exit) + } + /// A.K.A. ut.ut_exit + /// + /// Return (0, 0) on Non-Linux platform + #[cfg(not(any(target_os = "linux", target_os = "android")))] + pub fn exit_status(&self) -> (i16, i16) { + (0, 0) + } + /// Consumes the `Utmpx`, returning the underlying C struct utmpx + pub fn into_inner(self) -> utmpx { + self.inner + } + pub fn is_user_process(&self) -> bool { + !self.user().is_empty() && self.record_type() == USER_PROCESS + } + + /// Canonicalize host name using DNS + pub fn canon_host(&self) -> IOResult { + const AI_CANONNAME: libc::c_int = 0x2; + let host = self.host(); + let host = host.split(':').next().unwrap(); + let hints = libc::addrinfo { + ai_flags: AI_CANONNAME, + ai_family: 0, + ai_socktype: 0, + ai_protocol: 0, + ai_addrlen: 0, + ai_addr: ptr::null_mut(), + ai_canonname: ptr::null_mut(), + ai_next: ptr::null_mut(), + }; + let c_host = CString::new(host).unwrap(); + let mut res = ptr::null_mut(); + let status = unsafe { + libc::getaddrinfo( + c_host.as_ptr(), + ptr::null(), + &hints as *const _, + &mut res as *mut _, + ) + }; + if status == 0 { + let info: libc::addrinfo = unsafe { ptr::read(res as *const _) }; + // http://lists.gnu.org/archive/html/bug-coreutils/2006-09/msg00300.html + // says Darwin 7.9.0 getaddrinfo returns 0 but sets + // res->ai_canonname to NULL. + let ret = if info.ai_canonname.is_null() { + Ok(String::from(host)) + } else { + Ok(unsafe { CString::from_raw(info.ai_canonname).into_string().unwrap() }) + }; + unsafe { + libc::freeaddrinfo(res); + } + ret + } else { + Err(IOError::last_os_error()) + } + } + pub fn iter_all_records() -> UtmpxIter { + UtmpxIter + } +} + +/// Iterator of login records +pub struct UtmpxIter; + +impl UtmpxIter { + /// Sets the name of the utmpx-format file for the other utmpx functions to access. + /// + /// If not set, default record file will be used(file path depends on the target OS) + pub fn read_from(self, f: &str) -> Self { + // FixME: discuss and revise a rewrite which is correct and satisfies clippy/rustc + #[allow(clippy::temporary_cstring_as_ptr)] + let res = unsafe { utmpxname(CString::new(f).unwrap().as_ptr()) }; + if res != 0 { + println!("Warning: {}", IOError::last_os_error()); + } + unsafe { + setutxent(); + } + self + } +} + +impl Iterator for UtmpxIter { + type Item = Utmpx; + fn next(&mut self) -> Option { + unsafe { + let res = getutxent(); + if !res.is_null() { + Some(Utmpx { + inner: ptr::read(res as *const _), + }) + } else { + endutxent(); + None + } + } + } +} diff --git a/src/uucore/src/lib/features/wide.rs b/src/uucore/src/lib/features/wide.rs new file mode 100644 index 000000000..49ce575a7 --- /dev/null +++ b/src/uucore/src/lib/features/wide.rs @@ -0,0 +1,39 @@ +// This file is part of the uutils coreutils package. +// +// (c) Peter Atashian +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +use std::ffi::{OsStr, OsString}; +use std::os::windows::ffi::{OsStrExt, OsStringExt}; +pub trait ToWide { + fn to_wide(&self) -> Vec; + fn to_wide_null(&self) -> Vec; +} +impl ToWide for T +where + T: AsRef, +{ + fn to_wide(&self) -> Vec { + self.as_ref().encode_wide().collect() + } + fn to_wide_null(&self) -> Vec { + self.as_ref().encode_wide().chain(Some(0)).collect() + } +} +pub trait FromWide { + fn from_wide(wide: &[u16]) -> Self; + fn from_wide_null(wide: &[u16]) -> Self; +} +impl FromWide for String { + fn from_wide(wide: &[u16]) -> String { + OsString::from_wide(wide).to_string_lossy().into_owned() + } + fn from_wide_null(wide: &[u16]) -> String { + let len = wide.iter().take_while(|&&c| c != 0).count(); + OsString::from_wide(&wide[..len]) + .to_string_lossy() + .into_owned() + } +} diff --git a/src/uucore/src/lib/features/zero_copy.rs b/src/uucore/src/lib/features/zero_copy.rs new file mode 100644 index 000000000..1eb2c1547 --- /dev/null +++ b/src/uucore/src/lib/features/zero_copy.rs @@ -0,0 +1,148 @@ +use self::platform::*; + +use std::io::{self, Write}; + +mod platform; + +pub trait AsRawObject { + fn as_raw_object(&self) -> RawObject; +} + +pub trait FromRawObject: Sized { + /// # Safety + /// ToDO ... + unsafe fn from_raw_object(obj: RawObject) -> Option; +} + +// TODO: also make a SpliceWriter that takes an input fd and and output fd and uses splice() to +// transfer data +// TODO: make a TeeWriter or something that takes an input fd and two output fds and uses tee() to +// transfer to both output fds + +enum InnerZeroCopyWriter { + Platform(PlatformZeroCopyWriter), + Standard(T), +} + +impl Write for InnerZeroCopyWriter { + fn write(&mut self, buf: &[u8]) -> io::Result { + match self { + InnerZeroCopyWriter::Platform(ref mut writer) => writer.write(buf), + InnerZeroCopyWriter::Standard(ref mut writer) => writer.write(buf), + } + } + + fn flush(&mut self) -> io::Result<()> { + match self { + InnerZeroCopyWriter::Platform(ref mut writer) => writer.flush(), + InnerZeroCopyWriter::Standard(ref mut writer) => writer.flush(), + } + } +} + +pub struct ZeroCopyWriter { + /// This field is never used, but we need it to drop file descriptors + #[allow(dead_code)] + raw_obj_owner: Option, + + inner: InnerZeroCopyWriter, +} + +struct TransformContainer<'a, A: Write + AsRawObject + Sized, B: Write + Sized> { + /// This field is never used and probably could be converted into PhantomData, but might be + /// useful for restructuring later (at the moment it's basically left over from an earlier + /// design) + #[allow(dead_code)] + original: Option<&'a mut A>, + + transformed: Option, +} + +impl<'a, A: Write + AsRawObject + Sized, B: Write + Sized> Write for TransformContainer<'a, A, B> { + fn write(&mut self, bytes: &[u8]) -> io::Result { + self.transformed.as_mut().unwrap().write(bytes) + } + + fn flush(&mut self) -> io::Result<()> { + self.transformed.as_mut().unwrap().flush() + } +} + +impl<'a, A: Write + AsRawObject + Sized, B: Write + Sized> AsRawObject + for TransformContainer<'a, A, B> +{ + fn as_raw_object(&self) -> RawObject { + panic!("Test should never be used") + } +} + +impl ZeroCopyWriter { + pub fn new(writer: T) -> Self { + let raw_obj = writer.as_raw_object(); + match unsafe { PlatformZeroCopyWriter::new(raw_obj) } { + Ok(inner) => ZeroCopyWriter { + raw_obj_owner: Some(writer), + inner: InnerZeroCopyWriter::Platform(inner), + }, + _ => { + // creating the splice writer failed for whatever reason, so just make a default + // writer + ZeroCopyWriter { + raw_obj_owner: None, + inner: InnerZeroCopyWriter::Standard(writer), + } + } + } + } + + pub fn with_default<'a: 'b, 'b, F, W>( + writer: &'a mut T, + func: F, + ) -> ZeroCopyWriter + where + F: Fn(&'a mut T) -> W, + W: Write + Sized + 'b, + { + let raw_obj = writer.as_raw_object(); + match unsafe { PlatformZeroCopyWriter::new(raw_obj) } { + Ok(inner) => ZeroCopyWriter { + raw_obj_owner: Some(TransformContainer { + original: Some(writer), + transformed: None, + }), + inner: InnerZeroCopyWriter::Platform(inner), + }, + _ => { + // XXX: should func actually consume writer and leave it up to the user to save the value? + // maybe provide a default stdin method then? in some cases it would make more sense for the + // value to be consumed + let real_writer = func(writer); + ZeroCopyWriter { + raw_obj_owner: None, + inner: InnerZeroCopyWriter::Standard(TransformContainer { + original: None, + transformed: Some(real_writer), + }), + } + } + } + } + + // XXX: unsure how to get something like this working without allocating, so not providing it + /*pub fn stdout() -> ZeroCopyWriter { + let mut stdout = io::stdout(); + ZeroCopyWriter::with_default(&mut stdout, |stdout| { + stdout.lock() + }) + }*/ +} + +impl Write for ZeroCopyWriter { + fn write(&mut self, buf: &[u8]) -> io::Result { + self.inner.write(buf) + } + + fn flush(&mut self) -> io::Result<()> { + self.inner.flush() + } +} diff --git a/src/uucore/src/lib/features/zero_copy/platform.rs b/src/uucore/src/lib/features/zero_copy/platform.rs new file mode 100644 index 000000000..67e4354c5 --- /dev/null +++ b/src/uucore/src/lib/features/zero_copy/platform.rs @@ -0,0 +1,21 @@ +#[cfg(any(target_os = "linux", target_os = "android"))] +pub use self::linux::*; +#[cfg(unix)] +pub use self::unix::*; +#[cfg(windows)] +pub use self::windows::*; + +// Add any operating systems we support here +#[cfg(not(any(target_os = "linux", target_os = "android")))] +pub use self::default::*; + +#[cfg(any(target_os = "linux", target_os = "android"))] +mod linux; +#[cfg(unix)] +mod unix; +#[cfg(windows)] +mod windows; + +// Add any operating systems we support here +#[cfg(not(any(target_os = "linux", target_os = "android")))] +mod default; diff --git a/src/uucore/src/lib/features/zero_copy/platform/default.rs b/src/uucore/src/lib/features/zero_copy/platform/default.rs new file mode 100644 index 000000000..47239a361 --- /dev/null +++ b/src/uucore/src/lib/features/zero_copy/platform/default.rs @@ -0,0 +1,21 @@ +use crate::features::zero_copy::RawObject; + +use std::io::{self, Write}; + +pub struct PlatformZeroCopyWriter; + +impl PlatformZeroCopyWriter { + pub unsafe fn new(_obj: RawObject) -> Result { + Err(()) + } +} + +impl Write for PlatformZeroCopyWriter { + fn write(&mut self, _bytes: &[u8]) -> io::Result { + panic!("should never occur") + } + + fn flush(&mut self) -> io::Result<()> { + panic!("should never occur") + } +} diff --git a/src/uucore/src/lib/features/zero_copy/platform/linux.rs b/src/uucore/src/lib/features/zero_copy/platform/linux.rs new file mode 100644 index 000000000..e2bed3061 --- /dev/null +++ b/src/uucore/src/lib/features/zero_copy/platform/linux.rs @@ -0,0 +1,113 @@ +use std::io::{self, Write}; +use std::os::unix::io::RawFd; + +use libc::{O_APPEND, S_IFIFO, S_IFREG}; +use nix::errno::Errno; +use nix::fcntl::{fcntl, splice, vmsplice, FcntlArg, SpliceFFlags}; +use nix::sys::stat::{fstat, FileStat}; +use nix::sys::uio::IoVec; +use nix::unistd::pipe; +use platform_info::{PlatformInfo, Uname}; + +use crate::features::zero_copy::{FromRawObject, RawObject}; + +lazy_static::lazy_static! { + static ref IN_WSL: bool = { + let info = PlatformInfo::new().unwrap(); + info.release().contains("Microsoft") + }; +} + +pub struct PlatformZeroCopyWriter { + raw_obj: RawObject, + read_pipe: RawFd, + write_pipe: RawFd, + #[allow(clippy::type_complexity)] + write_fn: fn(&mut PlatformZeroCopyWriter, &[IoVec<&[u8]>], usize) -> io::Result, +} + +impl PlatformZeroCopyWriter { + pub unsafe fn new(raw_obj: RawObject) -> nix::Result { + if *IN_WSL { + // apparently WSL hasn't implemented vmsplice(), causing writes to fail + // thus, we will just say zero-copy doesn't work there rather than working + // around it + return Err(nix::Error::from(Errno::EOPNOTSUPP)); + } + + let stat_info: FileStat = fstat(raw_obj)?; + let access_mode: libc::c_int = fcntl(raw_obj, FcntlArg::F_GETFL)?; + + let is_regular = (stat_info.st_mode & S_IFREG) != 0; + let is_append = (access_mode & O_APPEND) != 0; + let is_fifo = (stat_info.st_mode & S_IFIFO) != 0; + + if is_regular && !is_append { + let (read_pipe, write_pipe) = pipe()?; + + Ok(PlatformZeroCopyWriter { + raw_obj, + read_pipe, + write_pipe, + write_fn: write_regular, + }) + } else if is_fifo { + Ok(PlatformZeroCopyWriter { + raw_obj, + read_pipe: Default::default(), + write_pipe: Default::default(), + write_fn: write_fifo, + }) + } else { + // FIXME: how to error? + Err(nix::Error::from(Errno::UnknownErrno)) + } + } +} + +impl FromRawObject for PlatformZeroCopyWriter { + unsafe fn from_raw_object(obj: RawObject) -> Option { + PlatformZeroCopyWriter::new(obj).ok() + } +} + +impl Write for PlatformZeroCopyWriter { + fn write(&mut self, buf: &[u8]) -> io::Result { + let iovec = &[IoVec::from_slice(buf)]; + + let func = self.write_fn; + func(self, iovec, buf.len()) + } + + fn flush(&mut self) -> io::Result<()> { + // XXX: not sure if we need anything else + Ok(()) + } +} + +fn write_regular( + writer: &mut PlatformZeroCopyWriter, + iovec: &[IoVec<&[u8]>], + len: usize, +) -> io::Result { + vmsplice(writer.write_pipe, iovec, SpliceFFlags::empty()) + .and_then(|_| { + splice( + writer.read_pipe, + None, + writer.raw_obj, + None, + len, + SpliceFFlags::empty(), + ) + }) + .map_err(|_| io::Error::last_os_error()) +} + +fn write_fifo( + writer: &mut PlatformZeroCopyWriter, + iovec: &[IoVec<&[u8]>], + _len: usize, +) -> io::Result { + vmsplice(writer.raw_obj, iovec, SpliceFFlags::empty()).map_err(|_| io::Error::last_os_error()) +} diff --git a/src/uucore/src/lib/features/zero_copy/platform/unix.rs b/src/uucore/src/lib/features/zero_copy/platform/unix.rs new file mode 100644 index 000000000..553549c9b --- /dev/null +++ b/src/uucore/src/lib/features/zero_copy/platform/unix.rs @@ -0,0 +1,18 @@ +use std::os::unix::io::{AsRawFd, FromRawFd, RawFd}; + +use crate::features::zero_copy::{AsRawObject, FromRawObject}; + +pub type RawObject = RawFd; + +impl AsRawObject for T { + fn as_raw_object(&self) -> RawObject { + self.as_raw_fd() + } +} + +// FIXME: check if this works right +impl FromRawObject for T { + unsafe fn from_raw_object(obj: RawObject) -> Option { + Some(T::from_raw_fd(obj)) + } +} diff --git a/src/uucore/src/lib/features/zero_copy/platform/windows.rs b/src/uucore/src/lib/features/zero_copy/platform/windows.rs new file mode 100644 index 000000000..8134bfda3 --- /dev/null +++ b/src/uucore/src/lib/features/zero_copy/platform/windows.rs @@ -0,0 +1,19 @@ +use std::os::windows::io::{AsRawHandle, FromRawHandle, RawHandle}; + +use crate::features::zero_copy::{AsRawObject, FromRawObject}; + +pub type RawObject = RawHandle; + +impl AsRawObject for T { + fn as_raw_object(&self) -> RawObject { + self.as_raw_handle() + } +} + +impl FromRawObject for T { + unsafe fn from_raw_object(obj: RawObject) -> Option { + Some(T::from_raw_handle(obj)) + } +} + +// TODO: see if there's some zero-copy stuff in Windows diff --git a/src/uucore/src/lib/lib.rs b/src/uucore/src/lib/lib.rs new file mode 100644 index 000000000..005759514 --- /dev/null +++ b/src/uucore/src/lib/lib.rs @@ -0,0 +1,91 @@ +// library ~ (core/bundler file) + +// Copyright (C) ~ Alex Lyon +// Copyright (C) ~ Roy Ivy III ; MIT license + +//## external crates + +extern crate wild; + +// * feature-gated external crates +#[cfg(feature = "failure")] +extern crate failure; +#[cfg(feature = "failure_derive")] +extern crate failure_derive; +#[cfg(all(feature = "lazy_static", target_os = "linux"))] +extern crate lazy_static; +#[cfg(feature = "nix")] +extern crate nix; +#[cfg(feature = "platform-info")] +extern crate platform_info; + +// * feature-gated external crates (re-shared as public internal modules) +#[cfg(feature = "libc")] +pub extern crate libc; +#[cfg(feature = "winapi")] +pub extern crate winapi; + +//## internal modules + +mod macros; // crate macros (macro_rules-type; exported to `crate::...`) + +mod features; // feature-gated code modules +mod mods; // core cross-platform modules + +// * cross-platform modules +pub use crate::mods::coreopts; +pub use crate::mods::panic; + +// * feature-gated modules +#[cfg(feature = "encoding")] +pub use crate::features::encoding; +#[cfg(feature = "fs")] +pub use crate::features::fs; +#[cfg(feature = "parse_time")] +pub use crate::features::parse_time; +#[cfg(feature = "zero-copy")] +pub use crate::features::zero_copy; + +// * (platform-specific) feature-gated modules +// ** non-windows +#[cfg(all(not(windows), feature = "mode"))] +pub use crate::features::mode; +// ** unix-only +#[cfg(all(unix, feature = "entries"))] +pub use crate::features::entries; +#[cfg(all(unix, feature = "process"))] +pub use crate::features::process; +#[cfg(all(unix, not(target_os = "fuchsia"), feature = "signals"))] +pub use crate::features::signals; +#[cfg(all( + unix, + not(target_os = "fuchsia"), + not(target_env = "musl"), + feature = "utmpx" +))] +pub use crate::features::utmpx; +// ** windows-only +#[cfg(all(windows, feature = "wide"))] +pub use crate::features::wide; + +//## core functions + +use std::ffi::OsString; + +pub trait Args: Iterator + Sized { + fn collect_str(self) -> Vec { + // FIXME: avoid unwrap() + self.map(|s| s.into_string().unwrap()).collect() + } +} + +impl + Sized> Args for T {} + +// args() ... +pub fn args() -> impl Iterator { + wild::args() +} + +pub fn args_os() -> impl Iterator { + wild::args_os() +} diff --git a/src/uucore/src/lib/macros.rs b/src/uucore/src/lib/macros.rs new file mode 100644 index 000000000..0aa6d8f0a --- /dev/null +++ b/src/uucore/src/lib/macros.rs @@ -0,0 +1,271 @@ +// This file is part of the uutils coreutils package. +// +// (c) Alex Lyon +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +#[macro_export] +macro_rules! executable( + () => ({ + let module = module_path!(); + let module = module.split("::").next().unwrap_or(module); + if &module[0..3] == "uu_" { + &module[3..] + } else { + module + } + }) +); + +#[macro_export] +macro_rules! show_error( + ($($args:tt)+) => ({ + eprint!("{}: error: ", executable!()); + eprintln!($($args)+); + }) +); + +#[macro_export] +macro_rules! show_warning( + ($($args:tt)+) => ({ + eprint!("{}: warning: ", executable!()); + eprintln!($($args)+); + }) +); + +#[macro_export] +macro_rules! show_info( + ($($args:tt)+) => ({ + eprint!("{}: ", executable!()); + eprintln!($($args)+); + }) +); + +#[macro_export] +macro_rules! show_usage_error( + ($($args:tt)+) => ({ + eprint!("{}: ", executable!()); + eprintln!($($args)+); + eprintln!("Try '{} --help' for more information.", executable!()); + }) +); + +#[macro_export] +macro_rules! crash( + ($exit_code:expr, $($args:tt)+) => ({ + show_error!($($args)+); + ::std::process::exit($exit_code) + }) +); + +#[macro_export] +macro_rules! exit( + ($exit_code:expr) => ({ + ::std::process::exit($exit_code) + }) +); + +#[macro_export] +macro_rules! crash_if_err( + ($exit_code:expr, $exp:expr) => ( + match $exp { + Ok(m) => m, + Err(f) => crash!($exit_code, "{}", f), + } + ) +); + +#[macro_export] +macro_rules! return_if_err( + ($exit_code:expr, $exp:expr) => ( + match $exp { + Ok(m) => m, + Err(f) => { + show_error!("{}", f); + return $exit_code; + } + } + ) +); + +#[macro_export] +macro_rules! safe_write( + ($fd:expr, $($args:tt)+) => ( + match write!($fd, $($args)+) { + Ok(_) => {} + Err(f) => panic!(f.to_string()) + } + ) +); + +#[macro_export] +macro_rules! safe_writeln( + ($fd:expr, $($args:tt)+) => ( + match writeln!($fd, $($args)+) { + Ok(_) => {} + Err(f) => panic!(f.to_string()) + } + ) +); + +#[macro_export] +macro_rules! safe_unwrap( + ($exp:expr) => ( + match $exp { + Ok(m) => m, + Err(f) => crash!(1, "{}", f.to_string()) + } + ) +); + +//-- message templates + +//-- message templates : general + +#[macro_export] +macro_rules! snippet_list_join_oxford { + ($conjunction:expr, $valOne:expr, $valTwo:expr) => ( + format!("{}, {} {}", $valOne, $conjunction, $valTwo) + ); + ($conjunction:expr, $valOne:expr, $valTwo:expr $(, $remaining_values:expr)*) => ( + format!("{}, {}", $valOne, snippet_list_join_inner!($conjunction, $valTwo $(, $remaining_values)*)) + ); +} + +#[macro_export] +macro_rules! snippet_list_join_or { + ($valOne:expr, $valTwo:expr) => ( + format!("{} or {}", $valOne, $valTwo) + ); + ($valOne:expr, $valTwo:expr $(, $remaining_values:expr)*) => ( + format!("{}, {}", $valOne, snippet_list_join_oxford!("or", $valTwo $(, $remaining_values)*)) + ); +} + +//-- message templates : invalid input + +#[macro_export] +macro_rules! msg_invalid_input { + ($reason: expr) => { + format!("invalid input: {}", $reason) + }; +} + +#[macro_export] +macro_rules! snippet_no_file_at_path { + ($path:expr) => { + format!("nonexistent path {}", $path) + }; +} + +// -- message templates : invalid input : flag + +#[macro_export] +macro_rules! msg_invalid_opt_use { + ($about:expr, $flag:expr) => { + msg_invalid_input!(format!("The '{}' option {}", $flag, $about)) + }; + ($about:expr, $long_flag:expr, $short_flag:expr) => { + msg_invalid_input!(format!( + "The '{}' ('{}') option {}", + $long_flag, $short_flag, $about + )) + }; +} + +#[macro_export] +macro_rules! msg_opt_only_usable_if { + ($clause:expr, $flag:expr) => { + msg_invalid_opt_use!(format!("only usable if {}", $clause), $flag) + }; + ($clause:expr, $long_flag:expr, $short_flag:expr) => { + msg_invalid_opt_use!( + format!("only usable if {}", $clause), + $long_flag, + $short_flag + ) + }; +} + +#[macro_export] +macro_rules! msg_opt_invalid_should_be { + ($expects:expr, $received:expr, $flag:expr) => { + msg_invalid_opt_use!( + format!("expects {}, but was provided {}", $expects, $received), + $flag + ) + }; + ($expects:expr, $received:expr, $long_flag:expr, $short_flag:expr) => { + msg_invalid_opt_use!( + format!("expects {}, but was provided {}", $expects, $received), + $long_flag, + $short_flag + ) + }; +} + +// -- message templates : invalid input : args + +#[macro_export] +macro_rules! msg_arg_invalid_value { + ($expects:expr, $received:expr) => { + msg_invalid_input!(format!( + "expects its argument to be {}, but was provided {}", + $expects, $received + )) + }; +} + +#[macro_export] +macro_rules! msg_args_invalid_value { + ($expects:expr, $received:expr) => { + msg_invalid_input!(format!( + "expects its arguments to be {}, but was provided {}", + $expects, $received + )) + }; + ($msg:expr) => { + msg_invalid_input!($msg) + }; +} + +#[macro_export] +macro_rules! msg_args_nonexistent_file { + ($received:expr) => { + msg_args_invalid_value!("paths to files", snippet_no_file_at_path!($received)) + }; +} + +#[macro_export] +macro_rules! msg_wrong_number_of_arguments { + () => { + msg_args_invalid_value!("wrong number of arguments") + }; + ($min:expr, $max:expr) => { + msg_args_invalid_value!(format!("expects {}-{} arguments", $min, $max)) + }; + ($exact:expr) => { + if $exact == 1 { + msg_args_invalid_value!("expects 1 argument") + } else { + msg_args_invalid_value!(format!("expects {} arguments", $exact)) + } + }; +} + +// -- message templates : invalid input : input combinations + +#[macro_export] +macro_rules! msg_expects_one_of { + ($valOne:expr $(, $remaining_values:expr)*) => ( + msg_invalid_input!(format!("expects one of {}", snippet_list_join_or!($valOne $(, $remaining_values)*))) + ); +} + +#[macro_export] +macro_rules! msg_expects_no_more_than_one_of { + ($valOne:expr $(, $remaining_values:expr)*) => ( + msg_invalid_input!(format!("expects no more than one of {}", snippet_list_join_or!($valOne $(, $remaining_values)*))) ; + ); +} diff --git a/src/uucore/src/lib/mods.rs b/src/uucore/src/lib/mods.rs new file mode 100644 index 000000000..0becc71bd --- /dev/null +++ b/src/uucore/src/lib/mods.rs @@ -0,0 +1,4 @@ +// mods ~ cross-platforms modules (core/bundler file) + +pub mod coreopts; +pub mod panic; diff --git a/src/uucore/src/lib/mods/coreopts.rs b/src/uucore/src/lib/mods/coreopts.rs new file mode 100644 index 000000000..f1e382a3e --- /dev/null +++ b/src/uucore/src/lib/mods/coreopts.rs @@ -0,0 +1,143 @@ +extern crate getopts; + +pub struct HelpText<'a> { + pub name: &'a str, + pub version: &'a str, + pub syntax: &'a str, + pub summary: &'a str, + pub long_help: &'a str, + pub display_usage: bool, +} + +pub struct CoreOptions<'a> { + options: getopts::Options, + help_text: HelpText<'a>, +} + +impl<'a> CoreOptions<'a> { + pub fn new(help_text: HelpText<'a>) -> Self { + let mut ret = CoreOptions { + options: getopts::Options::new(), + help_text, + }; + ret.options + .optflag("", "help", "print usage information") + .optflag("", "version", "print name and version number"); + ret + } + pub fn optflagopt( + &mut self, + short_name: &str, + long_name: &str, + desc: &str, + hint: &str, + ) -> &mut CoreOptions<'a> { + self.options.optflagopt(short_name, long_name, desc, hint); + self + } + pub fn optflag( + &mut self, + short_name: &str, + long_name: &str, + desc: &str, + ) -> &mut CoreOptions<'a> { + self.options.optflag(short_name, long_name, desc); + self + } + pub fn optflagmulti( + &mut self, + short_name: &str, + long_name: &str, + desc: &str, + ) -> &mut CoreOptions<'a> { + self.options.optflagmulti(short_name, long_name, desc); + self + } + pub fn optopt( + &mut self, + short_name: &str, + long_name: &str, + desc: &str, + hint: &str, + ) -> &mut CoreOptions<'a> { + self.options.optopt(short_name, long_name, desc, hint); + self + } + pub fn optmulti( + &mut self, + short_name: &str, + long_name: &str, + desc: &str, + hint: &str, + ) -> &mut CoreOptions<'a> { + self.options.optmulti(short_name, long_name, desc, hint); + self + } + pub fn usage(&self, summary: &str) -> String { + self.options.usage(summary) + } + pub fn parse(&mut self, args: Vec) -> getopts::Matches { + let matches = match self.options.parse(&args[1..]) { + Ok(m) => Some(m), + Err(f) => { + eprint!("{}: error: ", self.help_text.name); + eprintln!("{}", f); + ::std::process::exit(1); + } + } + .unwrap(); + if matches.opt_present("help") { + let usage_str = if self.help_text.display_usage { + format!( + "\n {}\n\n Reference\n", + self.options.usage(self.help_text.summary) + ) + .replace("Options:", " Options:") + } else { + String::new() + }; + print!( + " + {0} {1} + + {0} {2} +{3}{4} +", + self.help_text.name, + self.help_text.version, + self.help_text.syntax, + usage_str, + self.help_text.long_help + ); + crate::exit!(0); + } else if matches.opt_present("version") { + println!("{} {}", self.help_text.name, self.help_text.version); + crate::exit!(0); + } + matches + } +} + +#[macro_export] +macro_rules! app { + ($syntax: expr, $summary: expr, $long_help: expr) => { + uucore::coreopts::CoreOptions::new(uucore::coreopts::HelpText { + name: executable!(), + version: env!("CARGO_PKG_VERSION"), + syntax: $syntax, + summary: $summary, + long_help: $long_help, + display_usage: true, + }) + }; + ($syntax: expr, $summary: expr, $long_help: expr, $display_usage: expr) => { + uucore::coreopts::CoreOptions::new(uucore::coreopts::HelpText { + name: executable!(), + version: env!("CARGO_PKG_VERSION"), + syntax: $syntax, + summary: $summary, + long_help: $long_help, + display_usage: $display_usage, + }) + }; +} diff --git a/src/uucore/src/lib/mods/panic.rs b/src/uucore/src/lib/mods/panic.rs new file mode 100644 index 000000000..6947df2ac --- /dev/null +++ b/src/uucore/src/lib/mods/panic.rs @@ -0,0 +1,17 @@ +use std::panic; + +//## SIGPIPE handling background/discussions ... +//* `uutils` ~ , +//* rust and `rg` ~ , , + +pub fn mute_sigpipe_panic() { + let hook = panic::take_hook(); + panic::set_hook(Box::new(move |info| { + if let Some(res) = info.payload().downcast_ref::() { + if res.contains("Broken pipe") { + return; + } + } + hook(info) + })); +} diff --git a/src/uucore_procs/Cargo.toml b/src/uucore_procs/Cargo.toml new file mode 100644 index 000000000..774232777 --- /dev/null +++ b/src/uucore_procs/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "uucore_procs" +version = "0.0.4" +authors = ["Roy Ivy III "] +license = "MIT" +description = "uutils ~ 'uucore' proc-macros" + +homepage = "https://github.com/uutils/uucore/uucore_procs" +repository = "https://github.com/uutils/uucore/uucore_procs" +# readme = "README.md" +keywords = ["cross-platform", "proc-macros", "uucore", "uutils"] +# categories = ["os"] +edition = "2018" + +[lib] +proc-macro = true + +[dependencies] +proc-macro2 = "1.0" +quote = "1.0" +syn = { version="1.0" } + +[features] +default = [] +# * non-default features +debug = ["syn/extra-traits"] ## add Debug traits to syn structures (for `println!("{:?}", ...)`) diff --git a/src/uucore_procs/src/lib.rs b/src/uucore_procs/src/lib.rs new file mode 100644 index 000000000..aa77316ee --- /dev/null +++ b/src/uucore_procs/src/lib.rs @@ -0,0 +1,86 @@ +#![allow(dead_code)] // work-around for GH:rust-lang/rust#62127; maint: can be removed when MinSRV >= v1.38.0 +#![allow(unused_macros)] // work-around for GH:rust-lang/rust#62127; maint: can be removed when MinSRV >= v1.38.0 + +// Copyright (C) ~ Roy Ivy III ; MIT license + +extern crate proc_macro; + +//## rust proc-macro background info +//* ref: @@ +//* ref: [path construction from LitStr](https://oschwald.github.io/maxminddb-rust/syn/struct.LitStr.html) @@ + +//## proc_dbg macro +//* used to help debug the compile-time proc_macro code + +#[cfg(feature = "debug")] +macro_rules! proc_dbg { + ($x:expr) => { + dbg!($x) + }; +} +#[cfg(not(feature = "debug"))] +macro_rules! proc_dbg { + ($x:expr) => {}; +} + +//## main!() + +// main!( EXPR ) +// generates a `main()` function for utilities within the uutils group +// EXPR == syn::Expr::Lit::String | syn::Expr::Path::Ident ~ EXPR contains the lexical path to the utility `uumain()` function +//* NOTE: EXPR is ultimately expected to be a multi-segment lexical path (eg, `crate::func`); so, if a single segment path is provided, a trailing "::uumain" is automatically added +//* for more generic use (and future use of "eager" macros), EXPR may be in either STRING or IDENT form + +struct Tokens { + expr: syn::Expr, +} + +impl syn::parse::Parse for Tokens { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + Ok(Tokens { + expr: input.parse()?, + }) + } +} + +#[proc_macro] +#[cfg(not(test))] // work-around for GH:rust-lang/rust#62127; maint: can be removed when MinSRV >= v1.38.0 +pub fn main(stream: proc_macro::TokenStream) -> proc_macro::TokenStream { + let Tokens { expr } = syn::parse_macro_input!(stream as Tokens); + proc_dbg!(&expr); + + const ARG_PANIC_TEXT: &str = + "expected ident lexical path (or a literal string version) to 'uumain()' as argument"; + + // match EXPR as a string literal or an ident path, o/w panic!() + let mut expr = match expr { + syn::Expr::Lit(expr_lit) => match expr_lit.lit { + syn::Lit::Str(ref lit_str) => lit_str.parse::().unwrap(), + _ => panic!(ARG_PANIC_TEXT), + }, + syn::Expr::Path(expr_path) => expr_path, + _ => panic!(ARG_PANIC_TEXT), + }; + proc_dbg!(&expr); + + // for a single segment ExprPath argument, add trailing '::uumain' segment + if expr.path.segments.len() < 2 { + expr = syn::parse_quote!( #expr::uumain ); + }; + proc_dbg!(&expr); + + let f = quote::quote! { #expr(uucore::args_os()) }; + proc_dbg!(&f); + + // generate a uutils utility `main()` function, tailored for the calling utility + let result = quote::quote! { + fn main() { + use std::io::Write; + uucore::panic::mute_sigpipe_panic(); // suppress extraneous error output for SIGPIPE failures/panics + let code = #f; // execute utility code + std::io::stdout().flush().expect("could not flush stdout"); // (defensively) flush stdout for utility prior to exit; see + std::process::exit(code); + } + }; + proc_macro::TokenStream::from(result) +} diff --git a/tests/by-util/test_install.rs b/tests/by-util/test_install.rs index e9e70bd93..3fea04187 100644 --- a/tests/by-util/test_install.rs +++ b/tests/by-util/test_install.rs @@ -10,7 +10,7 @@ fn test_install_help() { .succeeds() .no_stderr() .stdout - .contains("Options:")); + .contains("FLAGS:")); } #[test] diff --git a/tests/by-util/test_mkdir.rs b/tests/by-util/test_mkdir.rs index 70e4e414c..73be9b253 100644 --- a/tests/by-util/test_mkdir.rs +++ b/tests/by-util/test_mkdir.rs @@ -13,6 +13,16 @@ fn test_mkdir_mkdir() { new_ucmd!().arg(TEST_DIR1).succeeds(); } +#[test] +fn test_mkdir_verbose() { + let expected = "mkdir: created directory 'mkdir_test1'\n"; + new_ucmd!() + .arg(TEST_DIR1) + .arg("-v") + .run() + .stdout_is(expected); +} + #[test] fn test_mkdir_dup_dir() { let scene = TestScenario::new(util_name!()); diff --git a/tests/by-util/test_rm.rs b/tests/by-util/test_rm.rs index 88e70946a..7c5a1c787 100644 --- a/tests/by-util/test_rm.rs +++ b/tests/by-util/test_rm.rs @@ -12,6 +12,14 @@ fn test_rm_one_file() { assert!(!at.file_exists(file)); } +#[test] +fn test_rm_failed() { + let (_at, mut ucmd) = at_and_ucmd!(); + let file = "test_rm_one_file"; + + ucmd.arg(file).fails(); // Doesn't exist +} + #[test] fn test_rm_multiple_files() { let (at, mut ucmd) = at_and_ucmd!(); diff --git a/tests/by-util/test_sync.rs b/tests/by-util/test_sync.rs index 651491045..e4eb72eac 100644 --- a/tests/by-util/test_sync.rs +++ b/tests/by-util/test_sync.rs @@ -1 +1,11 @@ -// ToDO: add tests +use crate::common::util::*; + +#[test] +fn test_sync_default() { + new_ucmd!().run(); +} + +#[test] +fn test_sync_incorrect_arg() { + new_ucmd!().arg("--foo").fails(); +}