Skip to content

Conversation

@Jasha10
Copy link
Contributor

@Jasha10 Jasha10 commented Nov 17, 2024

Add flag to cp builtin to enable creating hardlinks.

This make use of the -l/--links flag from coreutils' cp command.

Links:

User-Facing Changes

Should add extra flag to cp.
Default behavior of cp should not change

Tests + Formatting

Added some unit tests

TODO:

  • cargo fmt --all -- --check to check standard code formatting (cargo fmt --all applies these changes)
  • cargo clippy --workspace -- -D warnings -D clippy::unwrap_used to check that you're using the standard code style
  • cargo test --workspace to check that all tests pass (on Windows make sure to enable developer mode)
  • cargo run -- -c "use toolkit.nu; toolkit test stdlib" to run the tests for the standard library

Note
from nushell you can also use the toolkit as follows

use toolkit.nu  # or use an `env_change` hook to activate it automatically
toolkit check pr

-->

After Submitting

Comment on lines +50 to +51
.switch("link", "hard-link files instead of copying", Some('l'))
.switch("symbolic-link", "make symbolic links instead of copying", Some('s'))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flag names and descriptions are copied directly from the uutils.cp docs:
https://uutils.github.io/coreutils/docs/utils/cp.html

--link, -l
hard-link files instead of copying

...

--symbolic-link, -s
make symbolic links instead of copying

Comment on lines 112 to 126
let (update, copy_mode) = if call.has_flag(engine_state, stack, "update")? {
(UpdateMode::ReplaceIfOlder, CopyMode::Update)
let update = if call.has_flag(engine_state, stack, "update")? {
UpdateMode::ReplaceIfOlder
} else {
(UpdateMode::ReplaceAll, CopyMode::Copy)
UpdateMode::ReplaceAll
};
let copy_mode = if call.has_flag(engine_state, stack, "link")? {
CopyMode::Link
} else if call.has_flag(engine_state, stack, "symbolic-link")? {
CopyMode::SymLink
} else if call.has_flag(engine_state, stack, "update")? {
CopyMode::Update
} else {
CopyMode::Copy
Copy link
Contributor Author

@Jasha10 Jasha10 Nov 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tried to directly port the flag behavior from the uu_cp crate:
https://github.com/uutils/coreutils/blob/7e4ef50c82a7503cba05b97c1c37970b9b4c8346/src/uu/cp/src/cp.rs#L760-L782

impl CopyMode {
    fn from_matches(matches: &ArgMatches) -> Self {
        if matches.get_flag(options::LINK) {
            Self::Link
        } else if matches.get_flag(options::SYMBOLIC_LINK) {
            Self::SymLink
        } else if matches
            .get_one::<String>(update_control::arguments::OPT_UPDATE)
            .is_some()
            || matches.get_flag(update_control::arguments::OPT_UPDATE_NO_ARG)
        {
            Self::Update
        } else if matches.get_flag(options::ATTRIBUTES_ONLY) {
            if matches.get_flag(options::REMOVE_DESTINATION) {
                Self::Copy
            } else {
                Self::AttrOnly
            }
        } else {
            Self::Copy
        }
    }
}

I left out the logic regarding ATTRIBUTES_ONLY and REMOVE_DESTINATION because nushell's cp does not have those flags (yet).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My opinion is that, if nushell's cp continues to implement more flags with passthrough to uutils cp, then we should find a way to try and delegate the above sorts of switch logic to uutils's cp instead of reimplementing it. Copying the switch logic from uutils to nushell's codebase is more error prone and requires writing more tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants