1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-29 03:57:44 +00:00

refactor(hostname): use clap instead of getopts for consistency (#1516)

* refactor(hostname): use clap instead of getopts for consistency

* deps ~ uucore/wide is required

Co-authored-by: Roy Ivy III <rivy.dev@gmail.com>
This commit is contained in:
Sylvestre Ledru 2020-05-22 17:27:03 +02:00 committed by GitHub
parent 817a237821
commit 272b66aac8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 40 deletions

2
Cargo.lock generated
View file

@ -660,7 +660,7 @@ dependencies = [
name = "hostname" name = "hostname"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hostname 0.3.1 (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.62 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
"uucore 0.0.2 (git+https://github.com/uutils/uucore/?tag=0.0.2)", "uucore 0.0.2 (git+https://github.com/uutils/uucore/?tag=0.0.2)",

View file

@ -10,9 +10,9 @@ name = "uu_hostname"
path = "src/hostname.rs" path = "src/hostname.rs"
[dependencies] [dependencies]
getopts = "0.2" clap = "2.32"
libc = "0.2.42" libc = "0.2.42"
uucore = "0.0.2" uucore = { version = "0.0.2", features = [ "wide" ] }
winapi = { version = "0.3", features = ["sysinfoapi", "winsock2"] } winapi = { version = "0.3", features = ["sysinfoapi", "winsock2"] }
hostname = { version = "^0.3", features = ["set"] } hostname = { version = "^0.3", features = ["set"] }

View file

@ -9,7 +9,7 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
extern crate getopts; extern crate clap;
extern crate hostname; extern crate hostname;
extern crate libc; extern crate libc;
#[cfg(windows)] #[cfg(windows)]
@ -18,9 +18,8 @@ extern crate winapi;
#[macro_use] #[macro_use]
extern crate uucore; extern crate uucore;
use getopts::Matches; use clap::{App, Arg, ArgMatches};
use std::collections::hash_set::HashSet; use std::collections::hash_set::HashSet;
use std::ffi::OsStr;
use std::net::ToSocketAddrs; use std::net::ToSocketAddrs;
use std::str; use std::str;
@ -29,9 +28,14 @@ use winapi::shared::minwindef::MAKEWORD;
#[cfg(windows)] #[cfg(windows)]
use winapi::um::winsock2::{WSACleanup, WSAStartup}; use winapi::um::winsock2::{WSACleanup, WSAStartup};
const SYNTAX: &str = "[OPTION]... [HOSTNAME]"; static ABOUT: &str = "Display or set the system's host name.";
const SUMMARY: &str = "Print or set the system's host name."; static VERSION: &str = env!("CARGO_PKG_VERSION");
const LONG_HELP: &str = "";
static OPT_DOMAIN: &str = "domain";
static OPT_IP_ADDRESS: &str = "ip-address";
static OPT_FQDN: &str = "fqdn";
static OPT_SHORT: &str = "short";
static OPT_HOST: &str = "host";
pub fn uumain(args: Vec<String>) -> i32 { pub fn uumain(args: Vec<String>) -> i32 {
#![allow(clippy::let_and_return)] #![allow(clippy::let_and_return)]
@ -52,53 +56,58 @@ pub fn uumain(args: Vec<String>) -> i32 {
result result
} }
fn get_usage() -> String {
format!("{0} [OPTION]... [HOSTNAME]", executable!())
}
fn execute(args: Vec<String>) -> i32 { fn execute(args: Vec<String>) -> i32 {
let matches = new_coreopts!(SYNTAX, SUMMARY, LONG_HELP) let usage = get_usage();
.optflag( let matches = App::new(executable!())
"d", .version(VERSION)
"domain", .about(ABOUT)
"Display the name of the DNS domain if possible", .usage(&usage[..])
.arg(
Arg::with_name(OPT_DOMAIN)
.short("d")
.long("domain")
.help("Display the name of the DNS domain if possible"),
) )
.optflag( .arg(
"i", Arg::with_name(OPT_IP_ADDRESS)
"ip-address", .short("i")
"Display the network address(es) of the host", .long("ip-address")
.help("Display the network address(es) of the host"),
) )
// TODO: support --long // TODO: support --long
.optflag( .arg(
"f", Arg::with_name(OPT_FQDN)
"fqdn", .short("f")
"Display the FQDN (Fully Qualified Domain Name) (default)", .long("fqdn")
.help("Display the FQDN (Fully Qualified Domain Name) (default)"),
) )
.optflag( .arg(Arg::with_name(OPT_SHORT).short("s").long("short").help(
"s",
"short",
"Display the short hostname (the portion before the first dot) if \ "Display the short hostname (the portion before the first dot) if \
possible", possible",
) ))
.parse(args); .arg(Arg::with_name(OPT_HOST))
.get_matches_from(&args);
match matches.free.len() { match matches.value_of(OPT_HOST) {
0 => display_hostname(matches), None => display_hostname(&matches),
1 => { Some(host) => {
if let Err(err) = hostname::set(OsStr::new(matches.free.last().unwrap())) { if let Err(err) = hostname::set(host) {
show_error!("{}", err); show_error!("{}", err);
1 1
} else { } else {
0 0
} }
} }
_ => {
show_error!("{}", msg_wrong_number_of_arguments!(0, 1));
1
}
} }
} }
fn display_hostname(matches: Matches) -> i32 { fn display_hostname(matches: &ArgMatches) -> i32 {
let hostname = hostname::get().unwrap().into_string().unwrap(); let hostname = hostname::get().unwrap().into_string().unwrap();
if matches.opt_present("i") { if matches.is_present(OPT_IP_ADDRESS) {
// XXX: to_socket_addrs needs hostname:port so append a dummy port and remove it later. // XXX: to_socket_addrs needs hostname:port so append a dummy port and remove it later.
// This was originally supposed to use std::net::lookup_host, but that seems to be // This was originally supposed to use std::net::lookup_host, but that seems to be
// deprecated. Perhaps we should use the dns-lookup crate? // deprecated. Perhaps we should use the dns-lookup crate?
@ -134,10 +143,10 @@ fn display_hostname(matches: Matches) -> i32 {
} }
} }
} else { } else {
if matches.opt_present("s") || matches.opt_present("d") { if matches.is_present(OPT_SHORT) || matches.is_present(OPT_DOMAIN) {
let mut it = hostname.char_indices().filter(|&ci| ci.1 == '.'); let mut it = hostname.char_indices().filter(|&ci| ci.1 == '.');
if let Some(ci) = it.next() { if let Some(ci) = it.next() {
if matches.opt_present("s") { if matches.is_present(OPT_SHORT) {
println!("{}", &hostname[0..ci.0]); println!("{}", &hostname[0..ci.0]);
} else { } else {
println!("{}", &hostname[ci.0 + 1..]); println!("{}", &hostname[ci.0 + 1..]);