-
Notifications
You must be signed in to change notification settings - Fork 287
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
Deduplicate overlay-ports handling and avoid repeated querying of the filesystem for 'port' vs 'subdirectories' #1534
base: main
Are you sure you want to change the base?
Conversation
Behavior change: "shadowed" overlay port dirs are not loaded in 'load all' scenarios anymore.
return Unit{}; | ||
} | ||
|
||
return LocalizedString::from_raw(Strings::join("\n", errors)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think stopping at the first error rather than trying to return all of them would also be reasonable behavior, but that broke the ci
e2e test so I kept this join behavior. (I did not keep it for different values of --overlay-ports
....)
src/vcpkg/portfileprovider.cpp
Outdated
{ | ||
Debug::println("Using overlay: ", overlay); | ||
Debug::println("Using overlay-dir: ", overlay); | ||
|
||
Checks::msg_check_exit(VCPKG_LINE_INFO, | ||
vcpkg::is_directory(m_fs.status(overlay, VCPKG_LINE_INFO)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should get rid of this is_directory
check but that would be product change I didn't need to make so I left it.
@@ -21,6 +21,8 @@ | |||
#include <vcpkg/base/optional.h> | |||
#include <vcpkg/base/path.h> | |||
|
|||
#include <vcpkg/portfileprovider.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The other vcpkgpaths.h
things try very hard to only forward declare things. I did this because:
portfileprovider.h
itself looks fairly lightweight.- This avoids needing to edit most users of
VcpkgPaths::overlay_ports
.
} | ||
case OverlayPortKind::Directory: | ||
{ | ||
auto maybe_subdirectories = fs.try_get_directories_non_recursive(m_directory); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I considered caching this but decided that the number of times try_load_all_ports
is called in the same running vcpkg.exe
is functionally 0 or 1 and thus it wouldn't be worth it.
I'd prefer |
I think there is nothing to fix. Its a documentation issue at best.
This is just a misunderstanding of the option. |
What do you mean by 'fixed'? As far as I can tell the feature's behavior matches its intended behavior. That you can point
Perhaps. The problem is, without this feature, there was no way to configure what the user wanted. |
Just assume if there is subdirectories with vcpkg.json in it that the whole directory is a collection of ports and otherwise directory is considered to be a directly a port? As far as I understand the problem is:
In my opinion this directory structure does not make a lot of sense but you can decided to either error here or ignore the root vcpkg.json. |
We have at least 2 independent reports of users trying to do exactly this. |
Have you asked why they are doing that? Ideally you would want something like this:
but you can also go option b) and simply warn on the layout or ignore it. I don't see a reason to add another option even though that is the "safe" way. |
I mean you are adding a new option just for people with a strange file layout? Seems more like a case to tell them to adjust their layout to match what vcpkg would expect or come up with a default layout instead of adding another very similar option which makes learning about overlays more complicated. |
'I want all the vcpkg things to be in the same directory' is a reasonable ask. |
Then either:
For me the later option is the better route since it won't potentially break anybody. (or add a switch (--ignore-top-level-manifest-in-overlay-ports) instead of basically the same option with slightly different behavior) |
Maybe it's better to add a note to the docs about this behavior and suggest to use a subdirectory for overlay-ports. |
I would vote for that. Or is there a reasonable motivation for depending on the same manifest as port with a portfile? |
Unfortunately I believe one of the reports didn't use the same manifest as the one that happened to be reachable from the configured overlay-ports..... but at least warning about this seems like a good idea nonetheless. |
@ras0219-msft would like to add an explicit error if |
# Conflicts: # include/vcpkg/paragraphs.h # src/vcpkg/paragraphs.cpp
…anifest directory an error.
For the record, I am in favor of allowing overlay-port-dirs as the directory with the top level manifest. |
@AugP @JavierMatosD @ras0219-msft @vicroms and I discussed this today. Based on internal feedback plus feedback from the contributors above, we have decided to not ship this feature. I will retarget this PR to include the structural improvements to not have that be a wasted effort, and the docs PR that clarifies how overlay-ports works better. |
else | ||
{ | ||
// the directory didn't look like a port at all, consider it an overlay-port-dir | ||
m_kind = OverlayPortKind::Directory; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would expect that if Paragraphs::try_load_port
is successful it loaded a port...
Also I find it not so nice that m_kind
is initialized in the constructor (but not for all cases) and here again. Imho it would be nicer to determine that beforehand and maybe even have distinct types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would expect that if
Paragraphs::try_load_port
is successful it loaded a port...
You want try_load_port_required
for that. "There was no error but there is also no port of that name" is a valid success condition:
vcpkg-tool/include/vcpkg/paragraphs.h
Lines 38 to 41 in d176cbe
// If an error occurs, the Expected will be in the error state. | |
// Otherwise, if the port is known, the maybe_scfl.get()->source_control_file contains the loaded port information. | |
// Otherwise, maybe_scfl.get()->source_control_file is nullptr. | |
PortLoadResult try_load_port(const ReadOnlyFilesystem& fs, const PortLocation& port_location); |
Also I find it not so nice that m_kind is initialized in the constructor (but not for all cases) and here again. Imho it would be nicer to determine that beforehand and maybe even have distinct types.
The problem is that determining this answer requires hitting the disk and we have no reason to do that if we don't happen to consider this overlay-ports
entry in the first place.
This work originally added an "overlay-port-dirs" setting to allow a user to explicitly request the "the subdirectory contains port subdirectories" interpretation of an overlay-ports value rather than the "this is the overlay-port itself" interpretation.
After feedback from contributors, we re-evaluated adding this feature and decided to not do that. However, the infrastructure work that was done in support of the feature still has some value, so I've removed the user-facing part of the feature from this PR but kept most of the internal machinery.
Other notable behavior changes:
overlay-ports
to the provably same directory as a top-level manifest now generates an error, with a special error for"."
in the configuration file. Note thatoverlay-triplets
are not affected.load_all_control_files
family onOverlayPortProviderImpl
would load all ports in the lowest priority--overlay-ports
, then overwrite any of those with 'higher' values. This meant that malformed ports which vcpkg would never consider would be forced to be loaded, thus potentially triggering irrelevant errors.CONTROL
/vcpkg.json
declared a matching name, and some paths did not. Now, all paths consider ports with mismatched names an error rather than silently using the name invcpkg.json
.fs.exists
checks in order to determine if the indicated directory should contain the port or subdirectories that are ports; now, wetry_read_contents
and consider file not found as nonexistent, saving a disk operation.commands.install.cpp
no longer gets entirely broken in the 'add the builtin ports directory as an overlay' cases if there is avcpkg.json
in%VCPKG_ROOT%/ports
.Related:
Resolves: