From e72ec4a5bba6f680630da8828aa6ff8b9212cab8 Mon Sep 17 00:00:00 2001 From: Ben Eills Date: Tue, 12 Jul 2016 20:56:21 +0200 Subject: [PATCH] Implement skeleton install utility Add install utility skeleton source, based on mv, including the getopts setup mirroring GNU's `man install` documentation. Also add a single test and build system code. --- Cargo.lock | 31 ++++++++++++++ Cargo.toml | 2 + Makefile | 2 + src/install/Cargo.toml | 20 +++++++++ src/install/install.rs | 92 ++++++++++++++++++++++++++++++++++++++++++ src/install/main.rs | 5 +++ tests/test_install.rs | 21 ++++++++++ tests/tests.rs | 1 + 8 files changed, 174 insertions(+) create mode 100644 src/install/Cargo.toml create mode 100644 src/install/install.rs create mode 100644 src/install/main.rs create mode 100644 tests/test_install.rs diff --git a/Cargo.lock b/Cargo.lock index 931098e4d..4c0640ad4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,7 @@ dependencies = [ "basename 0.0.1", "cat 0.0.1", "chmod 0.0.1", + "chown 0.0.1", "chroot 0.0.1", "cksum 0.0.1", "comm 0.0.1", @@ -31,6 +32,7 @@ dependencies = [ "hostid 0.0.1", "hostname 0.0.1", "id 0.0.1", + "install 0.0.1", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "kill 0.0.1", "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -177,6 +179,17 @@ dependencies = [ "walker 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "chown" +version = "0.0.1" +dependencies = [ + "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.1", + "walkdir 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "chroot" version = "0.0.1" @@ -408,6 +421,15 @@ dependencies = [ "uucore 0.0.1", ] +[[package]] +name = "install" +version = "0.0.1" +dependencies = [ + "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "uucore 0.0.1", +] + [[package]] name = "itertools" version = "0.4.15" @@ -1204,6 +1226,15 @@ name = "vec_map" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "walkdir" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "walker" version = "1.0.0" diff --git a/Cargo.toml b/Cargo.toml index 5aea9e268..20c086236 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ unix = [ "hostid", "hostname", "id", + "install", "kill", "logname", "mkfifo", @@ -126,6 +127,7 @@ head = { optional=true, path="src/head" } hostid = { optional=true, path="src/hostid" } hostname = { optional=true, path="src/hostname" } id = { optional=true, path="src/id" } +install = { optional=true, path="src/install" } kill = { optional=true, path="src/kill" } link = { optional=true, path="src/link" } ln = { optional=true, path="src/ln" } diff --git a/Makefile b/Makefile index f43ddbb9d..77fa9222a 100644 --- a/Makefile +++ b/Makefile @@ -107,6 +107,7 @@ UNIX_PROGS := \ hostid \ hostname \ id \ + install \ kill \ logname \ mkfifo \ @@ -152,6 +153,7 @@ TEST_PROGS := \ fold \ hashsum \ head \ + install \ link \ ln \ ls \ diff --git a/src/install/Cargo.toml b/src/install/Cargo.toml new file mode 100644 index 000000000..87fe3d1f4 --- /dev/null +++ b/src/install/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "install" +version = "0.0.1" +authors = ["Ben Eills "] + +[lib] +name = "uu_install" +path = "install.rs" + +[dependencies] +getopts = "*" +libc = "*" +uucore = { path="../uucore" } + +[dev-dependencies] +time = "*" + +[[bin]] +name = "install" +path = "main.rs" diff --git a/src/install/install.rs b/src/install/install.rs new file mode 100644 index 000000000..db1724178 --- /dev/null +++ b/src/install/install.rs @@ -0,0 +1,92 @@ +#![crate_name = "uu_install"] + +/* + * This file is part of the uutils coreutils package. + * + * (c) Ben Eills + * + * For the full copyright and license information, please view the LICENSE file + * that was distributed with this source code. + */ + +extern crate getopts; +extern crate libc; + +#[macro_use] +extern crate uucore; + +use std::io::{Write}; +use std::path::{Path, PathBuf}; + +static NAME: &'static str = "install"; +static VERSION: &'static str = env!("CARGO_PKG_VERSION"); + +pub fn uumain(args: Vec) -> i32 { + let mut opts = getopts::Options::new(); + + opts.optflagopt("", "backup", "make a backup of each existing destination file", "CONTROL"); + opts.optflag("b", "", "like --backup but does not accept an argument"); + opts.optflag("C", "compare", "compare each pair of source and destination files, and in\n \ + some cases, do not modify the destination at all"); + opts.optflag("d", "directory", "treat all arguments as directory names; create all\n \ + components of the specified directories"); + + opts.optflag("D", "", "create all leading components of DEST except the last, then copy\n \ + SOURCE to DEST"); + opts.optflagopt("g", "group", "set group ownership, instead of process' current group", + "GROUP"); + opts.optflagopt("m", "mode", "set permission mode (as in chmod), instead of rwxr-xr-x", + "MODE"); + opts.optflagopt("o", "owner", "set ownership (super-user only)", + "OWNER"); + opts.optflag("p", "preserve-timestamps", "apply access/modification times of SOURCE files\n \ + to corresponding destination files"); + opts.optflag("s", "strip", "strip symbol tables"); + opts.optflagopt("", "strip-program", "program used to strip binaries", "PROGRAM"); + opts.optopt("S", "suffix", "override the usual backup suffix", "SUFFIX"); + opts.optopt("t", "target-directory", "move all SOURCE arguments into DIRECTORY", "DIRECTORY"); + opts.optflag("T", "no-target-directory", "treat DEST as a normal file"); + opts.optflag("v", "verbose", "explain what is being done"); + opts.optflag("P", "preserve-context", "preserve security context"); + opts.optflagopt("Z", "context", "set security context of files and directories", "CONTEXT"); + 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, + Err(f) => { + show_error!("Invalid options\n{}", f); + return 1; + } + }; + let usage = opts.usage("Copy SOURCE to DEST or multiple SOURCE(s) to the existing\n \ + DIRECTORY, while setting permission modes and owner/group"); + + let paths: Vec = { + fn string_to_path<'a>(s: &'a String) -> &'a 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() + }; + + if matches.opt_present("version") { + println!("{} {}", NAME, VERSION); + 0 + } else if matches.opt_present("help") { + help(&usage); + 0 + } else { + println!("Not implemented."); + 1 + } +} + +fn help(usage: &str) { + println!("{0} {1}\n\n\ + Usage: {0} SOURCE DEST\n \ + or: {0} SOURCE... DIRECTORY\n\n\ + {2}", NAME, VERSION, usage); +} diff --git a/src/install/main.rs b/src/install/main.rs new file mode 100644 index 000000000..fa1e578d8 --- /dev/null +++ b/src/install/main.rs @@ -0,0 +1,5 @@ +extern crate uu_install; + +fn main() { + std::process::exit(uu_install::uumain(std::env::args().collect())); +} diff --git a/tests/test_install.rs b/tests/test_install.rs new file mode 100644 index 000000000..e7fa061fc --- /dev/null +++ b/tests/test_install.rs @@ -0,0 +1,21 @@ +extern crate libc; +extern crate time; +extern crate kernel32; +extern crate winapi; +extern crate filetime; + +use self::filetime::*; +use common::util::*; + +static UTIL_NAME: &'static str = "install"; + +#[test] +fn test_install_help() { + let (at, mut ucmd) = testing(UTIL_NAME); + + let result = ucmd.arg("--help").run(); + assert_empty_stderr!(result); + assert!(result.success); + +// assert!(result.stdout.contains("Usage:")); +} diff --git a/tests/tests.rs b/tests/tests.rs index d867a934f..4a88f2d91 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -27,6 +27,7 @@ macro_rules! unix_only { unix_only! { "chmod", test_chmod; "chown", test_chown; + "install", test_install; "mv", test_mv; "pathchk", test_pathchk; "stdbuf", test_stdbuf;