mirror of
https://github.com/uutils/coreutils.git
synced 2026-06-10 15:48:22 -07:00
Merge branch 'main' into mktemp-set-dir-mode
This commit is contained in:
+22
-22
@@ -24,7 +24,7 @@ jobs:
|
||||
name: Style/cargo-deny
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: EmbarkStudios/cargo-deny-action@v1
|
||||
|
||||
style_deps:
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
- { os: macos-latest , features: "feat_Tier1,feat_require_unix,feat_require_unix_utmpx" }
|
||||
- { os: windows-latest , features: feat_os_windows }
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- name: Initialize workflow variables
|
||||
id: vars
|
||||
@@ -101,7 +101,7 @@ jobs:
|
||||
job:
|
||||
- { os: ubuntu-latest , features: feat_os_unix }
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- name: Initialize workflow variables
|
||||
id: vars
|
||||
@@ -165,7 +165,7 @@ jobs:
|
||||
- { os: macos-latest , features: feat_os_macos }
|
||||
- { os: windows-latest , features: feat_os_windows }
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- name: Initialize workflow variables
|
||||
id: vars
|
||||
@@ -223,7 +223,7 @@ jobs:
|
||||
job:
|
||||
- { os: ubuntu-latest , features: feat_os_unix }
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- name: Initialize workflow variables
|
||||
id: vars
|
||||
@@ -275,7 +275,7 @@ jobs:
|
||||
# - { os: macos-latest , features: feat_os_macos }
|
||||
# - { os: windows-latest , features: feat_os_windows }
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- name: Initialize workflow variables
|
||||
id: vars
|
||||
@@ -320,7 +320,7 @@ jobs:
|
||||
job:
|
||||
- { os: ubuntu-latest , features: feat_os_unix }
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- name: Initialize workflow variables
|
||||
id: vars
|
||||
@@ -397,7 +397,7 @@ jobs:
|
||||
job:
|
||||
- { os: ubuntu-latest , features: feat_os_unix }
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- name: Install `rust` toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
@@ -422,7 +422,7 @@ jobs:
|
||||
job:
|
||||
- { os: ubuntu-latest , features: feat_os_unix }
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- name: Install `rust` toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
@@ -452,7 +452,7 @@ jobs:
|
||||
- { os: macos-latest , features: feat_os_macos }
|
||||
- { os: windows-latest , features: feat_os_windows }
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- name: Install `rust` toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
@@ -478,7 +478,7 @@ jobs:
|
||||
- { os: macos-latest , features: feat_os_macos }
|
||||
- { os: windows-latest , features: feat_os_windows }
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- name: Install `rust` toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
@@ -502,7 +502,7 @@ jobs:
|
||||
job:
|
||||
- { os: ubuntu-latest , features: feat_os_unix }
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- name: Install dependencies
|
||||
shell: bash
|
||||
@@ -534,7 +534,7 @@ jobs:
|
||||
--arg size "$SIZE" \
|
||||
--arg multisize "$SIZEMULTI" \
|
||||
'{($date): { sha: $sha, size: $size, multisize: $multisize, }}' > size-result.json
|
||||
- uses: actions/upload-artifact@v2
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: size-result
|
||||
path: size-result.json
|
||||
@@ -568,7 +568,7 @@ jobs:
|
||||
- { os: windows-latest , target: x86_64-pc-windows-gnu , features: feat_os_windows } ## note: requires rust >= 1.43.0 to link correctly
|
||||
- { os: windows-latest , target: x86_64-pc-windows-msvc , features: feat_os_windows }
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- name: Initialize workflow variables
|
||||
id: vars
|
||||
@@ -762,7 +762,7 @@ jobs:
|
||||
args: --target=${{ matrix.job.target }} ${{ steps.vars.outputs.CARGO_TEST_OPTIONS}} ${{ matrix.job.cargo-options }} ${{ steps.dep_vars.outputs.CARGO_UTILITY_LIST_OPTIONS }}
|
||||
toolchain: ${{ env.RUST_MIN_SRV }}
|
||||
- name: Archive executable artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ env.PROJECT_NAME }}-${{ matrix.job.target }}
|
||||
path: target/${{ matrix.job.target }}/release/${{ env.PROJECT_NAME }}${{ steps.vars.outputs.EXE_suffix }}
|
||||
@@ -820,7 +820,7 @@ jobs:
|
||||
job:
|
||||
- { os: ubuntu-latest }
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- name: Install/setup prerequisites
|
||||
shell: bash
|
||||
@@ -857,9 +857,9 @@ jobs:
|
||||
env:
|
||||
TERMUX: v0.118.0
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: AVD cache
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
id: avd-cache
|
||||
with:
|
||||
path: |
|
||||
@@ -911,11 +911,11 @@ jobs:
|
||||
env:
|
||||
mem: 2048
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- name: Prepare, build and test
|
||||
## spell-checker:ignore (ToDO) sshfs usesh vmactions
|
||||
uses: vmactions/freebsd-vm@v0.1.5
|
||||
uses: vmactions/freebsd-vm@v0.1.6
|
||||
with:
|
||||
usesh: true
|
||||
# sync: sshfs
|
||||
@@ -979,7 +979,7 @@ jobs:
|
||||
- { os: macos-latest , features: macos }
|
||||
- { os: windows-latest , features: windows }
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
# - name: Reattach HEAD ## may be needed for accurate code coverage info
|
||||
# run: git checkout ${{ github.head_ref }}
|
||||
@@ -1100,7 +1100,7 @@ jobs:
|
||||
grcov . --output-type lcov --output-path "${COVERAGE_REPORT_FILE}" --branch --ignore build.rs --ignore "vendor/*" --ignore "/*" --ignore "[a-zA-Z]:/*" --excl-br-line "^\s*((debug_)?assert(_eq|_ne)?!|#\[derive\()"
|
||||
echo ::set-output name=report::${COVERAGE_REPORT_FILE}
|
||||
- name: Upload coverage results (to Codecov.io)
|
||||
uses: codecov/codecov-action@v1
|
||||
uses: codecov/codecov-action@v3
|
||||
# if: steps.vars.outputs.HAS_CODECOV_TOKEN
|
||||
with:
|
||||
# token: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
job:
|
||||
- { os: ubuntu-latest , features: feat_os_unix }
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- name: Initialize job variables
|
||||
id: vars
|
||||
@@ -80,7 +80,7 @@ jobs:
|
||||
## * using the 'stable' toolchain is necessary to avoid "unexpected '--filter-platform'" errors
|
||||
RUSTUP_TOOLCHAIN=stable cargo-tree tree --locked --all --no-dev-dependencies --no-indent --features ${{ matrix.job.features }} | grep -vE "$PWD" | sort --unique
|
||||
- name: Commit any changes (to '${{ env.BRANCH_TARGET }}')
|
||||
uses: EndBug/add-and-commit@v7
|
||||
uses: EndBug/add-and-commit@v9
|
||||
with:
|
||||
branch: ${{ env.BRANCH_TARGET }}
|
||||
default_author: github_actions
|
||||
@@ -100,7 +100,7 @@ jobs:
|
||||
job:
|
||||
- { os: ubuntu-latest , features: feat_os_unix }
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- name: Initialize job variables
|
||||
id: vars
|
||||
@@ -130,7 +130,7 @@ jobs:
|
||||
# `cargo fmt` of tests
|
||||
find tests -name "*.rs" -print0 | xargs -0 cargo fmt --
|
||||
- name: Commit any changes (to '${{ env.BRANCH_TARGET }}')
|
||||
uses: EndBug/add-and-commit@v7
|
||||
uses: EndBug/add-and-commit@v9
|
||||
with:
|
||||
branch: ${{ env.BRANCH_TARGET }}
|
||||
default_author: github_actions
|
||||
|
||||
@@ -41,11 +41,11 @@ jobs:
|
||||
TEST_FULL_SUMMARY_FILE='gnu-full-result.json'
|
||||
outputs SUITE_LOG_FILE TEST_FILESET_PREFIX TEST_FILESET_SUFFIX TEST_LOGS_GLOB TEST_SUMMARY_FILE TEST_FULL_SUMMARY_FILE
|
||||
- name: Checkout code (uutil)
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: '${{ steps.vars.outputs.path_UUTILS }}'
|
||||
- name: Checkout code (GNU coreutils)
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'coreutils/coreutils'
|
||||
path: '${{ steps.vars.outputs.path_GNU }}'
|
||||
@@ -146,22 +146,22 @@ jobs:
|
||||
# Compress logs before upload (fails otherwise)
|
||||
gzip ${{ steps.vars.outputs.TEST_LOGS_GLOB }}
|
||||
- name: Reserve SHA1/ID of 'test-summary'
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: "${{ steps.summary.outputs.HASH }}"
|
||||
path: "${{ steps.vars.outputs.TEST_SUMMARY_FILE }}"
|
||||
- name: Reserve test results summary
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: test-summary
|
||||
path: "${{ steps.vars.outputs.TEST_SUMMARY_FILE }}"
|
||||
- name: Reserve test logs
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: test-logs
|
||||
path: "${{ steps.vars.outputs.TEST_LOGS_GLOB }}"
|
||||
- name: Upload full json results
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: gnu-full-result.json
|
||||
path: ${{ steps.vars.outputs.TEST_FULL_SUMMARY_FILE }}
|
||||
@@ -229,11 +229,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code uutil
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: 'uutils'
|
||||
- name: Checkout GNU coreutils
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'coreutils/coreutils'
|
||||
path: 'gnu'
|
||||
@@ -293,7 +293,7 @@ jobs:
|
||||
grcov . --output-type lcov --output-path "${COVERAGE_REPORT_FILE}" --branch --ignore build.rs --ignore "vendor/*" --ignore "/*" --ignore "[a-zA-Z]:/*" --excl-br-line "^\s*((debug_)?assert(_eq|_ne)?!|#\[derive\()"
|
||||
echo ::set-output name=report::${COVERAGE_REPORT_FILE}
|
||||
- name: Upload coverage results (to Codecov.io)
|
||||
uses: codecov/codecov-action@v2
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
file: ${{ steps.coverage.outputs.report }}
|
||||
flags: gnutests
|
||||
|
||||
Generated
+4
-4
@@ -273,9 +273,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap_complete"
|
||||
version = "3.1.3"
|
||||
version = "3.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d7ca9141e27e6ebc52e3c378b0c07f3cea52db46ed1cc5861735fb697b56356"
|
||||
checksum = "da92e6facd8d73c22745a5d3cbb59bdf8e46e3235c923e516527d8e81eec14a4"
|
||||
dependencies = [
|
||||
"clap 3.1.15",
|
||||
]
|
||||
@@ -2027,9 +2027,9 @@ checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "unindent"
|
||||
version = "0.1.8"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "514672a55d7380da379785a4d70ca8386c8883ff7eaae877be4d2081cebe73d8"
|
||||
checksum = "52fee519a3e570f7df377a06a1a7775cdbfb7aa460be7e08de2b1f0e69973a44"
|
||||
|
||||
[[package]]
|
||||
name = "unix_socket"
|
||||
|
||||
@@ -123,7 +123,12 @@ pub fn base_app<'a>(about: &'a str, usage: &'a str) -> Command<'a> {
|
||||
)
|
||||
// "multiple" arguments are used to check whether there is more than one
|
||||
// file passed in.
|
||||
.arg(Arg::new(options::FILE).index(1).multiple_occurrences(true))
|
||||
.arg(
|
||||
Arg::new(options::FILE)
|
||||
.index(1)
|
||||
.multiple_occurrences(true)
|
||||
.value_hint(clap::ValueHint::FilePath),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_input<'a>(config: &Config, stdin_ref: &'a Stdin) -> UResult<Box<dyn Read + 'a>> {
|
||||
|
||||
@@ -102,6 +102,7 @@ pub fn uu_app<'a>() -> Command<'a> {
|
||||
.arg(
|
||||
Arg::new(options::NAME)
|
||||
.multiple_occurrences(true)
|
||||
.value_hint(clap::ValueHint::AnyPath)
|
||||
.hide(true),
|
||||
)
|
||||
.arg(
|
||||
|
||||
@@ -249,7 +249,8 @@ pub fn uu_app<'a>() -> Command<'a> {
|
||||
.arg(
|
||||
Arg::new(options::FILE)
|
||||
.hide(true)
|
||||
.multiple_occurrences(true),
|
||||
.multiple_occurrences(true)
|
||||
.value_hint(clap::ValueHint::FilePath),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(options::SHOW_ALL)
|
||||
|
||||
@@ -197,6 +197,7 @@ pub fn uu_app<'a>() -> Command<'a> {
|
||||
.long(options::REFERENCE)
|
||||
.takes_value(true)
|
||||
.value_name("RFILE")
|
||||
.value_hint(clap::ValueHint::FilePath)
|
||||
.conflicts_with_all(&[options::USER, options::ROLE, options::TYPE, options::RANGE])
|
||||
.help(
|
||||
"Use security context of RFILE, rather than specifying \
|
||||
@@ -210,6 +211,7 @@ pub fn uu_app<'a>() -> Command<'a> {
|
||||
.long(options::USER)
|
||||
.takes_value(true)
|
||||
.value_name("USER")
|
||||
.value_hint(clap::ValueHint::Username)
|
||||
.help("Set user USER in the target security context.")
|
||||
.allow_invalid_utf8(true),
|
||||
)
|
||||
@@ -294,6 +296,7 @@ pub fn uu_app<'a>() -> Command<'a> {
|
||||
.arg(
|
||||
Arg::new("FILE")
|
||||
.multiple_occurrences(true)
|
||||
.value_hint(clap::ValueHint::FilePath)
|
||||
.min_values(1)
|
||||
.allow_invalid_utf8(true),
|
||||
)
|
||||
|
||||
@@ -113,6 +113,7 @@ pub fn uu_app<'a>() -> Command<'a> {
|
||||
Arg::new(options::REFERENCE)
|
||||
.long(options::REFERENCE)
|
||||
.value_name("RFILE")
|
||||
.value_hint(clap::ValueHint::FilePath)
|
||||
.help("use RFILE's group rather than specifying GROUP values")
|
||||
.takes_value(true)
|
||||
.multiple_occurrences(false),
|
||||
|
||||
@@ -157,6 +157,7 @@ pub fn uu_app<'a>() -> Command<'a> {
|
||||
Arg::new(options::REFERENCE)
|
||||
.long("reference")
|
||||
.takes_value(true)
|
||||
.value_hint(clap::ValueHint::FilePath)
|
||||
.help("use RFILE's mode instead of MODE values"),
|
||||
)
|
||||
.arg(
|
||||
@@ -170,7 +171,8 @@ pub fn uu_app<'a>() -> Command<'a> {
|
||||
.arg(
|
||||
Arg::new(options::FILE)
|
||||
.required_unless_present(options::MODE)
|
||||
.multiple_occurrences(true),
|
||||
.multiple_occurrences(true)
|
||||
.value_hint(clap::ValueHint::AnyPath),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+46
-17
@@ -134,6 +134,7 @@ pub fn uu_app<'a>() -> Command<'a> {
|
||||
.long(options::REFERENCE)
|
||||
.help("use RFILE's owner and group rather than specifying OWNER:GROUP values")
|
||||
.value_name("RFILE")
|
||||
.value_hint(clap::ValueHint::FilePath)
|
||||
.min_values(1),
|
||||
)
|
||||
.arg(
|
||||
@@ -167,17 +168,18 @@ pub fn uu_app<'a>() -> Command<'a> {
|
||||
)
|
||||
}
|
||||
|
||||
/// Parse the username and groupname
|
||||
/// Parse the owner/group specifier string into a user ID and a group ID.
|
||||
///
|
||||
/// In theory, it should be username:groupname
|
||||
/// but ...
|
||||
/// it can user.name:groupname
|
||||
/// or username.groupname
|
||||
/// The `spec` can be of the form:
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `"owner:group"`,
|
||||
/// * `"owner"`,
|
||||
/// * `":group"`,
|
||||
///
|
||||
/// * `spec` - The input from the user
|
||||
/// * `sep` - Should be ':' or '.'
|
||||
/// and the owner or group can be specified either as an ID or a
|
||||
/// name. The `sep` argument specifies which character to use as a
|
||||
/// separator between the owner and group; calling code should set
|
||||
/// this to `':'`.
|
||||
fn parse_spec(spec: &str, sep: char) -> UResult<(Option<u32>, Option<u32>)> {
|
||||
assert!(['.', ':'].contains(&sep));
|
||||
let mut args = spec.splitn(2, sep);
|
||||
@@ -197,10 +199,17 @@ fn parse_spec(spec: &str, sep: char) -> UResult<(Option<u32>, Option<u32>)> {
|
||||
// So, try to parse it this way
|
||||
return parse_spec(spec, '.');
|
||||
} else {
|
||||
return Err(USimpleError::new(
|
||||
1,
|
||||
format!("invalid user: {}", spec.quote()),
|
||||
));
|
||||
// It's possible that the `user` string contains a
|
||||
// numeric user ID, in which case, we respect that.
|
||||
match user.parse() {
|
||||
Ok(uid) => uid,
|
||||
Err(_) => {
|
||||
return Err(USimpleError::new(
|
||||
1,
|
||||
format!("invalid user: {}", spec.quote()),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -208,11 +217,18 @@ fn parse_spec(spec: &str, sep: char) -> UResult<(Option<u32>, Option<u32>)> {
|
||||
None
|
||||
};
|
||||
let gid = if !group.is_empty() {
|
||||
Some(
|
||||
Group::locate(group)
|
||||
.map_err(|_| USimpleError::new(1, format!("invalid group: {}", spec.quote())))?
|
||||
.gid,
|
||||
)
|
||||
Some(match Group::locate(group) {
|
||||
Ok(g) => g.gid,
|
||||
Err(_) => match group.parse() {
|
||||
Ok(gid) => gid,
|
||||
Err(_) => {
|
||||
return Err(USimpleError::new(
|
||||
1,
|
||||
format!("invalid group: {}", spec.quote()),
|
||||
));
|
||||
}
|
||||
},
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@@ -231,4 +247,17 @@ mod test {
|
||||
assert!(format!("{}", parse_spec("::", ':').err().unwrap()).starts_with("invalid group: "));
|
||||
assert!(format!("{}", parse_spec("..", ':').err().unwrap()).starts_with("invalid group: "));
|
||||
}
|
||||
|
||||
/// Test for parsing IDs that don't correspond to a named user or group.
|
||||
#[test]
|
||||
fn test_parse_spec_nameless_ids() {
|
||||
// This assumes that there is no named user with ID 12345.
|
||||
assert!(matches!(parse_spec("12345", ':'), Ok((Some(12345), None))));
|
||||
// This assumes that there is no named group with ID 54321.
|
||||
assert!(matches!(parse_spec(":54321", ':'), Ok((None, Some(54321)))));
|
||||
assert!(matches!(
|
||||
parse_spec("12345:54321", ':'),
|
||||
Ok((Some(12345), Some(54321)))
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,6 +102,7 @@ pub fn uu_app<'a>() -> Command<'a> {
|
||||
.infer_long_args(true)
|
||||
.arg(
|
||||
Arg::new(options::NEWROOT)
|
||||
.value_hint(clap::ValueHint::DirPath)
|
||||
.hide(true)
|
||||
.required(true)
|
||||
.index(1),
|
||||
@@ -139,6 +140,7 @@ pub fn uu_app<'a>() -> Command<'a> {
|
||||
)
|
||||
.arg(
|
||||
Arg::new(options::COMMAND)
|
||||
.value_hint(clap::ValueHint::CommandName)
|
||||
.hide(true)
|
||||
.multiple_occurrences(true)
|
||||
.index(2),
|
||||
|
||||
@@ -150,6 +150,7 @@ pub fn uu_app<'a>() -> Command<'a> {
|
||||
.arg(
|
||||
Arg::new(options::FILE)
|
||||
.hide(true)
|
||||
.multiple_occurrences(true),
|
||||
.multiple_occurrences(true)
|
||||
.value_hint(clap::ValueHint::FilePath),
|
||||
)
|
||||
}
|
||||
|
||||
+10
-2
@@ -173,6 +173,14 @@ pub fn uu_app<'a>() -> Command<'a> {
|
||||
.default_value(options::DELIMITER_DEFAULT)
|
||||
.hide_default_value(true),
|
||||
)
|
||||
.arg(Arg::new(options::FILE_1).required(true))
|
||||
.arg(Arg::new(options::FILE_2).required(true))
|
||||
.arg(
|
||||
Arg::new(options::FILE_1)
|
||||
.required(true)
|
||||
.value_hint(clap::ValueHint::FilePath),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(options::FILE_2)
|
||||
.required(true)
|
||||
.value_hint(clap::ValueHint::FilePath),
|
||||
)
|
||||
}
|
||||
|
||||
+3
-1
@@ -314,6 +314,7 @@ pub fn uu_app<'a>() -> Command<'a> {
|
||||
.conflicts_with(options::NO_TARGET_DIRECTORY)
|
||||
.long(options::TARGET_DIRECTORY)
|
||||
.value_name(options::TARGET_DIRECTORY)
|
||||
.value_hint(clap::ValueHint::DirPath)
|
||||
.takes_value(true)
|
||||
.validator(|s| {
|
||||
if Path::new(s).is_dir() {
|
||||
@@ -464,7 +465,8 @@ pub fn uu_app<'a>() -> Command<'a> {
|
||||
// END TODO
|
||||
|
||||
.arg(Arg::new(options::PATHS)
|
||||
.multiple_occurrences(true))
|
||||
.multiple_occurrences(true)
|
||||
.value_hint(clap::ValueHint::AnyPath))
|
||||
}
|
||||
|
||||
#[uucore::main]
|
||||
|
||||
@@ -797,7 +797,12 @@ pub fn uu_app<'a>() -> Command<'a> {
|
||||
.long(options::ELIDE_EMPTY_FILES)
|
||||
.help("remove empty output files"),
|
||||
)
|
||||
.arg(Arg::new(options::FILE).hide(true).required(true))
|
||||
.arg(
|
||||
Arg::new(options::FILE)
|
||||
.hide(true)
|
||||
.required(true)
|
||||
.value_hint(clap::ValueHint::FilePath),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(options::PATTERN)
|
||||
.hide(true)
|
||||
|
||||
@@ -614,6 +614,7 @@ pub fn uu_app<'a>() -> Command<'a> {
|
||||
.arg(
|
||||
Arg::new(options::FILE)
|
||||
.hide(true)
|
||||
.multiple_occurrences(true)
|
||||
.multiple_occurrences(true)
|
||||
.value_hint(clap::ValueHint::FilePath)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -272,6 +272,7 @@ pub fn uu_app<'a>() -> Command<'a> {
|
||||
.short('f')
|
||||
.long(OPT_FILE)
|
||||
.takes_value(true)
|
||||
.value_hint(clap::ValueHint::FilePath)
|
||||
.help("like --date; once for each line of DATEFILE"),
|
||||
)
|
||||
.arg(
|
||||
@@ -303,6 +304,7 @@ pub fn uu_app<'a>() -> Command<'a> {
|
||||
.short('r')
|
||||
.long(OPT_REFERENCE)
|
||||
.takes_value(true)
|
||||
.value_hint(clap::ValueHint::AnyPath)
|
||||
.help("display the last modification time of FILE"),
|
||||
)
|
||||
.arg(
|
||||
|
||||
@@ -742,6 +742,7 @@ pub fn uu_app<'a>() -> Command<'a> {
|
||||
.long(options::INFILE)
|
||||
.overrides_with(options::INFILE)
|
||||
.takes_value(true)
|
||||
.value_hint(clap::ValueHint::FilePath)
|
||||
.require_equals(true)
|
||||
.value_name("FILE")
|
||||
.help("(alternatively if=FILE) specifies the file used for input. When not specified, stdin is used instead")
|
||||
@@ -751,6 +752,7 @@ pub fn uu_app<'a>() -> Command<'a> {
|
||||
.long(options::OUTFILE)
|
||||
.overrides_with(options::OUTFILE)
|
||||
.takes_value(true)
|
||||
.value_hint(clap::ValueHint::FilePath)
|
||||
.require_equals(true)
|
||||
.value_name("FILE")
|
||||
.help("(alternatively of=FILE) specifies the file used for output. When not specified, stdout is used instead")
|
||||
|
||||
+20
-2
@@ -7,7 +7,10 @@ use crate::OPT_BLOCKSIZE;
|
||||
use clap::ArgMatches;
|
||||
use std::{env, fmt};
|
||||
|
||||
use uucore::parse_size::{parse_size, ParseSizeError};
|
||||
use uucore::{
|
||||
display::Quotable,
|
||||
parse_size::{parse_size, ParseSizeError},
|
||||
};
|
||||
|
||||
/// The first ten powers of 1024.
|
||||
const IEC_BASES: [u128; 10] = [
|
||||
@@ -167,6 +170,15 @@ pub(crate) enum BlockSize {
|
||||
Bytes(u64),
|
||||
}
|
||||
|
||||
impl BlockSize {
|
||||
/// Returns the associated value
|
||||
pub(crate) fn as_u64(&self) -> u64 {
|
||||
match *self {
|
||||
Self::Bytes(n) => n,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for BlockSize {
|
||||
fn default() -> Self {
|
||||
if env::var("POSIXLY_CORRECT").is_ok() {
|
||||
@@ -180,7 +192,13 @@ impl Default for BlockSize {
|
||||
pub(crate) fn block_size_from_matches(matches: &ArgMatches) -> Result<BlockSize, ParseSizeError> {
|
||||
if matches.is_present(OPT_BLOCKSIZE) {
|
||||
let s = matches.value_of(OPT_BLOCKSIZE).unwrap();
|
||||
Ok(BlockSize::Bytes(parse_size(s)?))
|
||||
let bytes = parse_size(s)?;
|
||||
|
||||
if bytes > 0 {
|
||||
Ok(BlockSize::Bytes(bytes))
|
||||
} else {
|
||||
Err(ParseSizeError::ParseFailure(format!("{}", s.quote())))
|
||||
}
|
||||
} else {
|
||||
Ok(Default::default())
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user