Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't follow links when copying paths #1972

Closed
wants to merge 1 commit into from
Closed

Conversation

natebosch
Copy link
Member

The original intent of this method was to copy links as links, not to
deeply copy the content of linked directories. This was never tested and
the original implementation did not have this behavior.

Change behavior in place without a major version change since the new
behavior is what was intended. Add a test that both the sync and async
implementation copies links as links.

The original intent of this method was to copy links as links, not to
deeply copy the content of linked directories. This was never tested and
the original implementation did not have this behavior.

Change behavior in place without a major version change since the new
behavior is what was intended. Add a test that both the sync and async
implementation copies links as links.
@natebosch
Copy link
Member Author

Replacement for #1267

Copy link

PR Health

Breaking changes ✔️
Package Change Current Version New Version Needed Version Looking good?
io None 1.0.5 1.1.0-wip 1.0.5 ✔️
Changelog Entry ✔️
Package Changed Files

Changes to files need to be accounted for in their respective changelogs.

Coverage ✔️
File Coverage
pkgs/io/lib/src/copy_path.dart 💚 100 % ⬆️ 18 %

This check for test coverage is informational (issues shown here will not fail the PR).

API leaks ✔️

The following packages contain symbols visible in the public API, but not exported by the library. Export these symbols or remove them from your publicly visible API.

Package Leaked API symbols
License Headers ✔️
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
Files
no missing headers

All source files should start with a license header.

Unrelated files missing license headers
Files
pkgs/bazel_worker/benchmark/benchmark.dart
pkgs/bazel_worker/example/client.dart
pkgs/bazel_worker/example/worker.dart
pkgs/benchmark_harness/integration_test/perf_benchmark_test.dart
pkgs/boolean_selector/example/example.dart
pkgs/clock/lib/clock.dart
pkgs/clock/lib/src/clock.dart
pkgs/clock/lib/src/default.dart
pkgs/clock/lib/src/stopwatch.dart
pkgs/clock/lib/src/utils.dart
pkgs/clock/test/clock_test.dart
pkgs/clock/test/default_test.dart
pkgs/clock/test/stopwatch_test.dart
pkgs/clock/test/utils.dart
pkgs/html/example/main.dart
pkgs/html/lib/dom.dart
pkgs/html/lib/dom_parsing.dart
pkgs/html/lib/html_escape.dart
pkgs/html/lib/parser.dart
pkgs/html/lib/src/constants.dart
pkgs/html/lib/src/encoding_parser.dart
pkgs/html/lib/src/html_input_stream.dart
pkgs/html/lib/src/list_proxy.dart
pkgs/html/lib/src/query_selector.dart
pkgs/html/lib/src/token.dart
pkgs/html/lib/src/tokenizer.dart
pkgs/html/lib/src/treebuilder.dart
pkgs/html/lib/src/utils.dart
pkgs/html/test/dom_test.dart
pkgs/html/test/parser_feature_test.dart
pkgs/html/test/parser_test.dart
pkgs/html/test/query_selector_test.dart
pkgs/html/test/selectors/level1_baseline_test.dart
pkgs/html/test/selectors/level1_lib.dart
pkgs/html/test/selectors/selectors.dart
pkgs/html/test/support.dart
pkgs/html/test/tokenizer_test.dart
pkgs/pubspec_parse/test/git_uri_test.dart
pkgs/stack_trace/example/example.dart
pkgs/watcher/test/custom_watcher_factory_test.dart
pkgs/yaml_edit/example/example.dart

@gmpassos
Copy link
Contributor

Please do not change the current behavior of this function, as the proposed change does not resolve any issue and does not provide an option to retain the existing behavior for backward compatibility.

This function has been working reliably for 8 years, and such a change risks breaking numerous third-party implementations. If the current behavior requires clarification, I recommend improving its documentation rather than altering it. Many third-party systems may not detect this change during testing, leading to failures in production.

@gmpassos
Copy link
Contributor

Replacement for #1267

It is not a replacement, as this PR still imposes only one behavior.

@natebosch
Copy link
Member Author

does not provide an option to retain the existing behavior for backward compatibility

Long term backwards compatibility is not generally a goal for packages published under tools.dart.dev.

We could certainly consider a major version bump along with this change, I think the both the cost and benefit of a major version bump along with this behavior change are pretty small. It would resolve concerns about silently breaking use cases outside of our internal tools, and require a pubspec change in some number of packages throughout the ecosystem.

It is not a replacement, as this PR still imposes only one behavior.

It's not clear to me that we have a use case for both behaviors, so imposing one behavior is our preferred approach. As I mentioned in the other thread, if we do think that both behaviors have concrete use cases, I'd want to deliver them in different ways.

@gmpassos
Copy link
Contributor

Long term backwards compatibility is not generally a goal for packages published under tools.dart.dev.

IMHO, whenever possible and simple to implement, backward compatibility should be preserved, especially for general-use packages like io.

It's not clear to me that we have a use case for both behaviors.

Yes, there are many situations where behavior A or B may be required. This often depends on the developer and the specific software that will use this package.

I believe it is simple to add a well-documented parameter, such as your suggestion for bool deepCopyLinkedContent = true (#1267).

I really respect the debate about the change, the correct parameter name, and the originally intended behavior before merging a PR. If you need any help with the final version of this change or its tests, let me know.

@natebosch
Copy link
Member Author

Yes, there are many situations where behavior A or B may be required.

Do you have a specific concrete use case for both behaviors that you can share?

@gmpassos
Copy link
Contributor

Yes, there are many situations where behavior A or B may be required.

Do you have a specific concrete use case for both behaviors that you can share?

  • deepCopyLinkedContent: true:

    • Performs a simple local backup.
    • Creates a real copy between two physical volumes (e.g., a removable volume), ensuring no linked files/directories are created.
  • deepCopyLinkedContent: false:

    • Copies locally without duplicating files (preserves links).
    • Produces an exact copy of a directory tree, including links (like a move, without removing the original file/dir).

@natebosch
Copy link
Member Author

especially for general-use packages like io.

To be clear, package:io, like other packages in the tools.dart.dev publisher is not intended for general-use. It is intended for the specific use of Dart team authored tooling.

See https://pub.dev/publishers/tools.dart.dev/packages and https://dart.dev/resources/dart-team-packages

We think it's good when the community is able to reuse our code, but we don't design or maintain the APIs with external use as the primary goal. When we have specific known third party use cases we consider them and often can easily accommodate them. I don't intend to influence API design based on speculative third party use cases.

@natebosch
Copy link
Member Author

natebosch commented Jan 16, 2025

Yes, there are many situations where behavior A or B may be required.

Do you have a specific concrete use case for both behaviors that you can share?

  • deepCopyLinkedContent: true:

    • Performs a simple local backup.
    • Creates a real copy between two physical volumes (e.g., a removable volume), ensuring no linked files/directories are created.
  • deepCopyLinkedContent: false:

    • Copies locally without duplicating files (preserves links).
    • Produces an exact copy of a directory tree, including links (like a move, without removing the original file/dir).

I understand the two behaviors and can speculate on use cases, but I don't know the specific concrete use cases for both behaviors. I certainly believe that you have a concrete use case for not deeply copying links, since you opened the PR in the first place, and it was the intended behavior so our original concrete internal use case may have wanted it. I have so far not seen evidence of a concrete use case requiring the current behavior and using this code.

@gmpassos
Copy link
Contributor

To be clear, package:io, like other packages in the tools.dart.dev publisher is not intended for general-use. It is intended for the specific use of Dart team authored tooling.

I didn't know that.

If you check the package io on pub.dev, there's no information about this.

@natebosch
Copy link
Member Author

natebosch commented Jan 16, 2025

To be clear, package:io, like other packages in the tools.dart.dev publisher is not intended for general-use. It is intended for the specific use of Dart team authored tooling.

I didn't know that.

If you check the package io on pub.dev, there's no information about this.

The publisher is linked at the top of the sidebar to the right.

image

The packages that are authored with the primary intent of serving third party use cases will link to the dart.dev publisher.

https://pub.dev/publishers/dart.dev/packages

@natebosch
Copy link
Member Author

  • between two physical volumes

I overlooked that copyPath won't work at all across volumes if there are links and we change the behavior. I will have to rethink whether a boolean argument is indeed the best API considering that limitation.

@gmpassos
Copy link
Contributor

The packages that are authored with the primary intent of serving third party use cases will link to the dart.dev publisher.

Ok, but this seems to be internal knowledge, people won't go to tools.dart.dev page to select a package, they will read the README, examples and API.

@natebosch
Copy link
Member Author

closing in favor of #1267 to handle cross device copies, I'll add tests there

@natebosch natebosch closed this Jan 16, 2025
@natebosch natebosch deleted the copy-path-links branch January 16, 2025 01:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants