From 722de2835bee779e0aa007bd5e561e5ab8be2081 Mon Sep 17 00:00:00 2001 From: codicodi Date: Mon, 10 Apr 2017 11:00:52 +0200 Subject: Add sdl2-mixer --- ports/sdl2-mixer/CMakeLists.txt | 95 +++++++++++++++++++++++++++++++++++++++++ ports/sdl2-mixer/CONTROL | 4 ++ ports/sdl2-mixer/portfile.cmake | 26 +++++++++++ 3 files changed, 125 insertions(+) create mode 100644 ports/sdl2-mixer/CMakeLists.txt create mode 100644 ports/sdl2-mixer/CONTROL create mode 100644 ports/sdl2-mixer/portfile.cmake diff --git a/ports/sdl2-mixer/CMakeLists.txt b/ports/sdl2-mixer/CMakeLists.txt new file mode 100644 index 000000000..094912b48 --- /dev/null +++ b/ports/sdl2-mixer/CMakeLists.txt @@ -0,0 +1,95 @@ +cmake_minimum_required(VERSION 3.0) +project(SDL2_MIXER C) + +find_path(SDL_INCLUDE_DIR SDL.h PATH_SUFFIXES SDL2) +find_library(SDL_LIBRARY SDL2) +set(SDL_MIXER_INCLUDES ${SDL_INCLUDE_DIR}) +set(SDL_MIXER_LIBRARIES ${SDL_LIBRARY}) + +# builtin formats +set(SDL_MIXER_DEFINES + WAV_MUSIC + MID_MUSIC + USE_NATIVE_MIDI) + +# MP3 support +if(SDL_MIXER_ENABLE_MP3) + find_path(SMPEG_INCLUDE_DIR smpeg.h) + find_library(SMPEG_LIBRARY smpeg2) + list(APPEND SDL_MIXER_INCLUDES ${SMPEG_INCLUDE_DIR}) + list(APPEND SDL_MIXER_LIBRARIES ${SMPEG_LIBRARY}) + list(APPEND SDL_MIXER_DEFINES MP3_MUSIC) +endif() + +# FLAC support +if(SDL_MIXER_ENABLE_FLAC) + find_path(FLAC_INCLUDE_DIR flac/all.h) + find_library(FLAC_LIBRARY flac) + list(APPEND SDL_MIXER_INCLUDES ${FLAC_INCLUDE_DIR}) + list(APPEND SDL_MIXER_LIBRARIES ${FLAC_LIBRARY}) + list(APPEND SDL_MIXER_DEFINES FLAC_MUSIC) +endif() + +# MOD support +if(SDL_MIXER_ENABLE_MOD) + find_path(MODPLUG_INCLUDE_DIR libmodplug/modplug.h) + find_library(MODPLUG_LIBRARY modplug) + list(APPEND SDL_MIXER_INCLUDES ${MODPLUG_INCLUDE_DIR}) + list(APPEND SDL_MIXER_LIBRARIES ${MODPLUG_LIBRARY}) + list(APPEND SDL_MIXER_DEFINES MODPLUG_MUSIC) +endif() + +# Ogg-Vorbis support +if(SDL_MIXER_ENABLE_OGGVORBIS) + find_path(VORBIS_INCLUDE_DIR vorbis/codec.h) + find_library(VORBISFILE_LIBRARY vorbisfile) + list(APPEND SDL_MIXER_INCLUDES ${VORBIS_INCLUDE_DIR}) + list(APPEND SDL_MIXER_LIBRARIES ${VORBISFILE_LIBRARY}) + list(APPEND SDL_MIXER_DEFINES OGG_MUSIC) +endif() + +add_library(SDL2_mixer + dynamic_flac.c + dynamic_fluidsynth.c + dynamic_mod.c + dynamic_modplug.c + dynamic_mp3.c + dynamic_ogg.c + effect_position.c + effect_stereoreverse.c + effects_internal.c + fluidsynth.c + load_aiff.c + load_flac.c + load_mp3.c + load_ogg.c + load_voc.c + mixer.c + music.c + music_cmd.c + music_flac.c + music_mad.c + music_mod.c + music_modplug.c + music_ogg.c + wavestream.c + native_midi/native_midi_common.c + native_midi/native_midi_win32.c) + +target_compile_definitions(SDL2_mixer PRIVATE ${SDL_MIXER_DEFINES}) +target_include_directories(SDL2_mixer PRIVATE ${SDL_MIXER_INCLUDES} ./native_midi) +target_link_libraries(SDL2_mixer ${SDL_MIXER_LIBRARIES} Winmm) + +install(TARGETS SDL2_mixer + RUNTIME DESTINATION bin + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib) + +if(NOT SDL_MIXER_SKIP_HEADERS) + install(FILES SDL_mixer.h DESTINATION include/SDL2) +endif() + +message(STATUS "Link-time dependencies:") +foreach(LIBRARY ${SDL_MIXER_LIBRARIES}) + message(STATUS " " ${LIBRARY}) +endforeach() diff --git a/ports/sdl2-mixer/CONTROL b/ports/sdl2-mixer/CONTROL new file mode 100644 index 000000000..b5d51aecd --- /dev/null +++ b/ports/sdl2-mixer/CONTROL @@ -0,0 +1,4 @@ +Source: sdl2-mixer +Version: 2.0.1 +Description: Multi-channel audio mixer library for SDL. +Build-Depends: sdl2, libflac, smpeg2, libmodplug, libvorbis diff --git a/ports/sdl2-mixer/portfile.cmake b/ports/sdl2-mixer/portfile.cmake new file mode 100644 index 000000000..574e6a1e0 --- /dev/null +++ b/ports/sdl2-mixer/portfile.cmake @@ -0,0 +1,26 @@ +include(vcpkg_common_functions) +set(SOURCE_PATH ${CURRENT_BUILDTREES_DIR}/src/SDL2_mixer-2.0.1) +vcpkg_download_distfile(ARCHIVE + URLS "https://www.libsdl.org/projects/SDL_mixer/release/SDL2_mixer-2.0.1.zip" + FILENAME "SDL2_mixer-2.0.1.zip" + SHA512 7399f08c5b091698c90d49fcc2996677eae8a36f05a65b4470807c9cf2c04730669e0ca395893cfa49177a929f8c5b2b10b6c541ba2fe2646300dcdad4ec1d9e) + +vcpkg_extract_source_archive(${ARCHIVE}) +file(COPY ${CMAKE_CURRENT_LIST_DIR}/CMakeLists.txt DESTINATION ${SOURCE_PATH}) + +vcpkg_configure_cmake( + SOURCE_PATH ${SOURCE_PATH} + PREFER_NINJA + OPTIONS + -DSDL_MIXER_ENABLE_MP3=ON # smpeg2 + -DSDL_MIXER_ENABLE_FLAC=ON # libflac + -DSDL_MIXER_ENABLE_MOD=ON # libmodplug + -DSDL_MIXER_ENABLE_OGGVORBIS=ON # libvorbis + OPTIONS_DEBUG + -DSDL_MIXER_SKIP_HEADERS=ON) + +vcpkg_install_cmake() +vcpkg_copy_pdbs() + +file(COPY ${SOURCE_PATH}/COPYING.txt DESTINATION ${CURRENT_PACKAGES_DIR}/share/sdl2-mixer) +file(RENAME ${CURRENT_PACKAGES_DIR}/share/sdl2-mixer/COPYING.txt ${CURRENT_PACKAGES_DIR}/share/sdl2-mixer/copyright) -- cgit v1.2.3 From bc019c7389284e1c90b4e123a96a94897ea84733 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 11 Apr 2017 17:17:50 -0700 Subject: Update EXAMPLES.md Because purge is now the default behavior of `remove`, packages are not "quickly" reinstallable using `install`. --- docs/EXAMPLES.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/EXAMPLES.md b/docs/EXAMPLES.md index 73b0d3048..c8bbdbefe 100644 --- a/docs/EXAMPLES.md +++ b/docs/EXAMPLES.md @@ -62,7 +62,6 @@ PS D:\src\vcpkg> .\vcpkg install sqlite3 -- Performing post-build validation done Package sqlite3:x86-windows is installed ``` -In addition to installing, `vcpkg` caches a pristine copy of the built library inside the `packages\` directory -- in this case, `packages\sqlite3_x86-windows`. This allows you to quickly uninstall and reinstall the library in the future using the `remove` and `install` commands. We can check that sqlite3 was successfully installed for x86 windows desktop by running the `list` command. ``` -- cgit v1.2.3 From 8780614392b43d628a8f7905ff4f367bc1fa9881 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 11 Apr 2017 17:21:20 -0700 Subject: Update EXAMPLES.md Change "15" Preview reference to 2017 --- docs/EXAMPLES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/EXAMPLES.md b/docs/EXAMPLES.md index c8bbdbefe..7331bd81c 100644 --- a/docs/EXAMPLES.md +++ b/docs/EXAMPLES.md @@ -92,7 +92,7 @@ Installing new libraries will make them instantly available. ``` *Note: You will need to restart Visual Studio or perform a Build to update intellisense with the changes.* -You can now simply use File -> New Project in Visual Studio 2015 or Visual Studio "15" Preview and the library will be automatically available. For Sqlite, you can try out their [C/C++ sample](https://sqlite.org/quickstart.html). +You can now simply use File -> New Project in Visual Studio 2015 or Visual Studio 2017 and the library will be automatically available. For Sqlite, you can try out their [C/C++ sample](https://sqlite.org/quickstart.html). To remove the integration for your user, you can use `.\vcpkg integrate remove`. -- cgit v1.2.3 From 612d941afc1339154354145f6fa5264d3c573cc0 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 10 Apr 2017 18:45:44 -0700 Subject: toposort: use lambda to obtain the neighbours of a vertex --- toolsrc/include/vcpkg_Graphs.h | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/toolsrc/include/vcpkg_Graphs.h b/toolsrc/include/vcpkg_Graphs.h index 933d9ac67..fb57a38db 100644 --- a/toolsrc/include/vcpkg_Graphs.h +++ b/toolsrc/include/vcpkg_Graphs.h @@ -20,20 +20,23 @@ namespace vcpkg::Graphs template class Graph { + template static void find_topological_sort_internal(V vertex, ExplorationStatus& status, - const std::unordered_map>& adjacency_list, + const Func adjacency_list_provider, std::unordered_map& exploration_status, std::vector& sorted) { status = ExplorationStatus::PARTIALLY_EXPLORED; - for (V neighbour : adjacency_list.at(vertex)) + auto neighbours = adjacency_list_provider(vertex); + + for (V neighbour : neighbours) { ExplorationStatus& neighbour_status = exploration_status[neighbour]; if (neighbour_status == ExplorationStatus::NOT_EXPLORED) { - find_topological_sort_internal(neighbour, neighbour_status, adjacency_list, exploration_status, sorted); + find_topological_sort_internal(neighbour, neighbour_status, adjacency_list_provider, exploration_status, sorted); } else if (neighbour_status == ExplorationStatus::PARTIALLY_EXPLORED) { @@ -85,7 +88,11 @@ namespace vcpkg::Graphs ExplorationStatus& status = exploration_status[vertex]; if (status == ExplorationStatus::NOT_EXPLORED) { - find_topological_sort_internal(vertex, status, this->vertices, exploration_status, sorted); + find_topological_sort_internal(vertex, + status, + [this](const V& v) { return this->vertices.at(v); }, + exploration_status, + sorted); } } } -- cgit v1.2.3 From cfbfa0d81327b32478e57cda85059c6063cd4bfd Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 11 Apr 2017 14:30:49 -0700 Subject: Rename --- toolsrc/include/vcpkg_Graphs.h | 8 ++++---- toolsrc/src/vcpkg_Dependencies.cpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/toolsrc/include/vcpkg_Graphs.h b/toolsrc/include/vcpkg_Graphs.h index fb57a38db..b97f7ac50 100644 --- a/toolsrc/include/vcpkg_Graphs.h +++ b/toolsrc/include/vcpkg_Graphs.h @@ -21,7 +21,7 @@ namespace vcpkg::Graphs class Graph { template - static void find_topological_sort_internal(V vertex, + static void topological_sort_internal(V vertex, ExplorationStatus& status, const Func adjacency_list_provider, std::unordered_map& exploration_status, @@ -36,7 +36,7 @@ namespace vcpkg::Graphs ExplorationStatus& neighbour_status = exploration_status[neighbour]; if (neighbour_status == ExplorationStatus::NOT_EXPLORED) { - find_topological_sort_internal(neighbour, neighbour_status, adjacency_list_provider, exploration_status, sorted); + topological_sort_internal(neighbour, neighbour_status, adjacency_list_provider, exploration_status, sorted); } else if (neighbour_status == ExplorationStatus::PARTIALLY_EXPLORED) { @@ -70,7 +70,7 @@ namespace vcpkg::Graphs this->vertices[u].insert(v); } - std::vector find_topological_sort() const + std::vector topological_sort() const { std::unordered_map indegrees = count_indegrees(); @@ -88,7 +88,7 @@ namespace vcpkg::Graphs ExplorationStatus& status = exploration_status[vertex]; if (status == ExplorationStatus::NOT_EXPLORED) { - find_topological_sort_internal(vertex, + topological_sort_internal(vertex, status, [this](const V& v) { return this->vertices.at(v); }, exploration_status, diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index 67c2c45a9..e47162953 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -114,7 +114,7 @@ namespace vcpkg::Dependencies std::vector ret; - const std::vector pkgs = graph.find_topological_sort(); + const std::vector pkgs = graph.topological_sort(); for (const PackageSpec& pkg : pkgs) { ret.push_back(PackageSpecWithInstallPlan(pkg, std::move(was_examined[pkg]))); @@ -171,7 +171,7 @@ namespace vcpkg::Dependencies std::vector ret; - const std::vector pkgs = graph.find_topological_sort(); + const std::vector pkgs = graph.topological_sort(); for (const PackageSpec& pkg : pkgs) { ret.push_back(PackageSpecWithRemovePlan(pkg, std::move(was_examined[pkg]))); -- cgit v1.2.3 From d7466d98bb192952a31255bee53c9d74192dedd6 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 11 Apr 2017 14:44:14 -0700 Subject: Extract toposort into a free function --- toolsrc/include/vcpkg_Graphs.h | 72 +++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 29 deletions(-) diff --git a/toolsrc/include/vcpkg_Graphs.h b/toolsrc/include/vcpkg_Graphs.h index b97f7ac50..1f90710fd 100644 --- a/toolsrc/include/vcpkg_Graphs.h +++ b/toolsrc/include/vcpkg_Graphs.h @@ -17,39 +17,55 @@ namespace vcpkg::Graphs FULLY_EXPLORED }; - template - class Graph + template + static void topological_sort_internal(V vertex, + ExplorationStatus& status, + const Func adjacency_list_provider, + std::unordered_map& exploration_status, + std::vector& sorted) { - template - static void topological_sort_internal(V vertex, - ExplorationStatus& status, - const Func adjacency_list_provider, - std::unordered_map& exploration_status, - std::vector& sorted) - { - status = ExplorationStatus::PARTIALLY_EXPLORED; + status = ExplorationStatus::PARTIALLY_EXPLORED; - auto neighbours = adjacency_list_provider(vertex); + auto neighbours = adjacency_list_provider(vertex); - for (V neighbour : neighbours) + for (V neighbour : neighbours) + { + ExplorationStatus& neighbour_status = exploration_status[neighbour]; + if (neighbour_status == ExplorationStatus::NOT_EXPLORED) { - ExplorationStatus& neighbour_status = exploration_status[neighbour]; - if (neighbour_status == ExplorationStatus::NOT_EXPLORED) - { - topological_sort_internal(neighbour, neighbour_status, adjacency_list_provider, exploration_status, sorted); - } - else if (neighbour_status == ExplorationStatus::PARTIALLY_EXPLORED) - { - throw std::runtime_error("cycle in graph"); - } + topological_sort_internal(neighbour, neighbour_status, adjacency_list_provider, exploration_status, sorted); } + else if (neighbour_status == ExplorationStatus::PARTIALLY_EXPLORED) + { + throw std::runtime_error("cycle in graph"); + } + } + status = ExplorationStatus::FULLY_EXPLORED; + sorted.push_back(vertex); + } - status = ExplorationStatus::FULLY_EXPLORED; - sorted.push_back(vertex); + template + std::vector topological_sort(const std::vector& starting_vertices, const Func adjacency_list_provider) + { + std::vector sorted; + std::unordered_map exploration_status; + + for (auto& vertex : starting_vertices) + { + ExplorationStatus& status = exploration_status[vertex]; + if (status == ExplorationStatus::NOT_EXPLORED) + { + topological_sort_internal(vertex, status, adjacency_list_provider, exploration_status, sorted); + } } - public: + return sorted; + } + template + class Graph + { + public: void add_vertex(V v) { this->vertices[v]; @@ -88,11 +104,9 @@ namespace vcpkg::Graphs ExplorationStatus& status = exploration_status[vertex]; if (status == ExplorationStatus::NOT_EXPLORED) { - topological_sort_internal(vertex, - status, - [this](const V& v) { return this->vertices.at(v); }, - exploration_status, - sorted); + topological_sort_internal(vertex, status, + [this](const V& v) { return this->vertices.at(v); }, + exploration_status, sorted); } } } -- cgit v1.2.3 From 24ba9f94ea346e3ce79441a4752a4f635d410088 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 11 Apr 2017 17:44:35 -0700 Subject: Parameter by const& --- toolsrc/include/vcpkg_Graphs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolsrc/include/vcpkg_Graphs.h b/toolsrc/include/vcpkg_Graphs.h index 1f90710fd..3ba26c017 100644 --- a/toolsrc/include/vcpkg_Graphs.h +++ b/toolsrc/include/vcpkg_Graphs.h @@ -18,7 +18,7 @@ namespace vcpkg::Graphs }; template - static void topological_sort_internal(V vertex, + static void topological_sort_internal(const V& vertex, ExplorationStatus& status, const Func adjacency_list_provider, std::unordered_map& exploration_status, -- cgit v1.2.3 From 58f46ab6527b79fcef59cf828133aa9092cba3eb Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Tue, 11 Apr 2017 19:37:38 -0700 Subject: Rework toposort and create_install_plan --- toolsrc/include/vcpkg_Dependencies.h | 12 +++ toolsrc/include/vcpkg_Graphs.h | 90 +++++++++++-------- toolsrc/src/vcpkg_Dependencies.cpp | 168 ++++++++++++++++++++++------------- 3 files changed, 172 insertions(+), 98 deletions(-) diff --git a/toolsrc/include/vcpkg_Dependencies.h b/toolsrc/include/vcpkg_Dependencies.h index 0e629ffef..36dd3cb2d 100644 --- a/toolsrc/include/vcpkg_Dependencies.h +++ b/toolsrc/include/vcpkg_Dependencies.h @@ -4,9 +4,20 @@ #include "StatusParagraphs.h" #include "VcpkgPaths.h" #include "vcpkg_optional.h" +#include "Paragraphs.h" namespace vcpkg::Dependencies { + struct AnyParagraph + { + std::vector edges() const; + + PackageSpec spec; + Optional status_paragraph; + Optional binary_paragraph; + Optional source_paragraph; + }; + enum class RequestType { UNKNOWN, @@ -27,6 +38,7 @@ namespace vcpkg::Dependencies struct InstallPlanAction { InstallPlanAction(); + explicit InstallPlanAction(const AnyParagraph& any_paragraph, const RequestType& request_type); InstallPlanAction(const InstallPlanType& plan_type, const RequestType& request_type, Optional binary_pgh, Optional source_pgh); InstallPlanAction(const InstallPlanAction&) = delete; InstallPlanAction(InstallPlanAction&&) = default; diff --git a/toolsrc/include/vcpkg_Graphs.h b/toolsrc/include/vcpkg_Graphs.h index 3ba26c017..8af2ad053 100644 --- a/toolsrc/include/vcpkg_Graphs.h +++ b/toolsrc/include/vcpkg_Graphs.h @@ -17,51 +17,76 @@ namespace vcpkg::Graphs FULLY_EXPLORED }; - template - static void topological_sort_internal(const V& vertex, - ExplorationStatus& status, - const Func adjacency_list_provider, - std::unordered_map& exploration_status, - std::vector& sorted) + template + __interface AdjacencyProvider { - status = ExplorationStatus::PARTIALLY_EXPLORED; + std::vector adjacency_list(const U& vertex) const; - auto neighbours = adjacency_list_provider(vertex); + U load_vertex_data(const V& vertex) const; + }; - for (V neighbour : neighbours) + template + static void topological_sort_internal(const V& vertex, + const AdjacencyProvider& f, + std::unordered_map& exploration_status, + std::vector& sorted) + { + ExplorationStatus& status = exploration_status[vertex]; + switch (status) { - ExplorationStatus& neighbour_status = exploration_status[neighbour]; - if (neighbour_status == ExplorationStatus::NOT_EXPLORED) - { - topological_sort_internal(neighbour, neighbour_status, adjacency_list_provider, exploration_status, sorted); - } - else if (neighbour_status == ExplorationStatus::PARTIALLY_EXPLORED) - { - throw std::runtime_error("cycle in graph"); - } + case ExplorationStatus::FULLY_EXPLORED: + return; + case ExplorationStatus::PARTIALLY_EXPLORED: + Checks::exit_with_message(VCPKG_LINE_INFO, "cycle in graph"); + case ExplorationStatus::NOT_EXPLORED: + { + status = ExplorationStatus::PARTIALLY_EXPLORED; + const U& vertex_data = f.load_vertex_data(vertex); + for (const V& neighbour : f.adjacency_list(vertex_data)) + topological_sort_internal(neighbour, f, exploration_status, sorted); + + sorted.push_back(std::move(vertex_data)); + status = ExplorationStatus::FULLY_EXPLORED; + return; + } + default: + Checks::unreachable(VCPKG_LINE_INFO); } - status = ExplorationStatus::FULLY_EXPLORED; - sorted.push_back(vertex); } - template - std::vector topological_sort(const std::vector& starting_vertices, const Func adjacency_list_provider) + template + std::vector topological_sort(const std::vector& starting_vertices, const AdjacencyProvider& f) { - std::vector sorted; + std::vector sorted; std::unordered_map exploration_status; for (auto& vertex : starting_vertices) { - ExplorationStatus& status = exploration_status[vertex]; - if (status == ExplorationStatus::NOT_EXPLORED) - { - topological_sort_internal(vertex, status, adjacency_list_provider, exploration_status, sorted); - } + topological_sort_internal(vertex, f, exploration_status, sorted); } return sorted; } + template + struct GraphAdjacencyProvider final : AdjacencyProvider + { + const std::unordered_map>& vertices; + + GraphAdjacencyProvider(const std::unordered_map>& vertices) : vertices(vertices) {} + + std::vector adjacency_list(const V& vertex) const override + { + const std::unordered_set& as_set = this->vertices.at(vertex); + return std::vector(as_set.cbegin(), as_set.cend()); // TODO: Avoid redundant copy + } + + V load_vertex_data(const V& vertex) const override + { + return vertex; + } + }; + template class Graph { @@ -88,6 +113,7 @@ namespace vcpkg::Graphs std::vector topological_sort() const { + GraphAdjacencyProvider adjacency_provider{ this->vertices }; std::unordered_map indegrees = count_indegrees(); std::vector sorted; @@ -101,13 +127,7 @@ namespace vcpkg::Graphs if (pair.second == 0) // Starting from vertices with indegree == 0. Not required. { V vertex = pair.first; - ExplorationStatus& status = exploration_status[vertex]; - if (status == ExplorationStatus::NOT_EXPLORED) - { - topological_sort_internal(vertex, status, - [this](const V& v) { return this->vertices.at(v); }, - exploration_status, sorted); - } + topological_sort_internal(vertex, adjacency_provider, exploration_status, sorted); } } diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index e47162953..3a53c42d1 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -5,10 +5,38 @@ #include "PackageSpec.h" #include "StatusParagraphs.h" #include "vcpkg_Files.h" -#include "Paragraphs.h" +#include "vcpkg_Util.h" namespace vcpkg::Dependencies { + std::vector AnyParagraph::edges() const + { + auto to_package_specs = [&](const std::vector& dependencies_as_string) + { + return Util::fmap(dependencies_as_string, [&](const std::string s) + { + return PackageSpec::from_name_and_triplet(s, this->spec.triplet()).value_or_exit(VCPKG_LINE_INFO); + }); + }; + + if (auto p = this->status_paragraph.get()) + { + return to_package_specs(p->package.depends); + } + + if (auto p = this->binary_paragraph.get()) + { + return to_package_specs(p->depends); + } + + if (auto p = this->source_paragraph.get()) + { + return to_package_specs(filter_dependencies(p->depends, this->spec.triplet())); + } + + Checks::exit_with_message(VCPKG_LINE_INFO, "Cannot get dependencies for package %s because there was none of: source/binary/status paragraphs", spec.to_string()); + } + std::string to_output_string(RequestType request_type, const CStringView s) { switch (request_type) @@ -22,21 +50,58 @@ namespace vcpkg::Dependencies } } - InstallPlanAction::InstallPlanAction() : plan_type(InstallPlanType::UNKNOWN), request_type(RequestType::UNKNOWN), binary_pgh(nullopt), source_pgh(nullopt) { } + InstallPlanAction::InstallPlanAction() : plan_type(InstallPlanType::UNKNOWN) + , request_type(RequestType::UNKNOWN) + , binary_pgh(nullopt) + , source_pgh(nullopt) { } + + InstallPlanAction::InstallPlanAction(const AnyParagraph& any_paragraph, const RequestType& request_type) : InstallPlanAction() + { + this->request_type = request_type; + if (any_paragraph.status_paragraph.get()) + { + this->plan_type = InstallPlanType::ALREADY_INSTALLED; + return; + } + + if (auto p = any_paragraph.binary_paragraph.get()) + { + this->plan_type = InstallPlanType::INSTALL; + this->binary_pgh = *p; + return; + } + + if (auto p = any_paragraph.source_paragraph.get()) + { + this->plan_type = InstallPlanType::BUILD_AND_INSTALL; + this->source_pgh = *p; + return; + } + + this->plan_type = InstallPlanType::UNKNOWN; + } InstallPlanAction::InstallPlanAction(const InstallPlanType& plan_type, const RequestType& request_type, Optional binary_pgh, Optional source_pgh) - : plan_type(std::move(plan_type)), request_type(request_type), binary_pgh(std::move(binary_pgh)), source_pgh(std::move(source_pgh)) { } + : plan_type(std::move(plan_type)) + , request_type(request_type) + , binary_pgh(std::move(binary_pgh)) + , source_pgh(std::move(source_pgh)) { } bool PackageSpecWithInstallPlan::compare_by_name(const PackageSpecWithInstallPlan* left, const PackageSpecWithInstallPlan* right) { return left->spec.name() < right->spec.name(); } - PackageSpecWithInstallPlan::PackageSpecWithInstallPlan(const PackageSpec& spec, InstallPlanAction&& plan) : spec(spec), plan(std::move(plan)) { } + PackageSpecWithInstallPlan::PackageSpecWithInstallPlan(const PackageSpec& spec, InstallPlanAction&& plan) + : spec(spec) + , plan(std::move(plan)) { } - RemovePlanAction::RemovePlanAction() : plan_type(RemovePlanType::UNKNOWN), request_type(RequestType::UNKNOWN) { } + RemovePlanAction::RemovePlanAction() : plan_type(RemovePlanType::UNKNOWN) + , request_type(RequestType::UNKNOWN) { } - RemovePlanAction::RemovePlanAction(const RemovePlanType& plan_type, const Dependencies::RequestType& request_type) : plan_type(plan_type), request_type(request_type) { } + RemovePlanAction::RemovePlanAction(const RemovePlanType& plan_type, const RequestType& request_type) + : plan_type(plan_type) + , request_type(request_type) { } bool PackageSpecWithRemovePlan::compare_by_name(const PackageSpecWithRemovePlan* left, const PackageSpecWithRemovePlan* right) { @@ -44,80 +109,57 @@ namespace vcpkg::Dependencies } PackageSpecWithRemovePlan::PackageSpecWithRemovePlan(const PackageSpec& spec, RemovePlanAction&& plan) - : spec(spec), plan(std::move(plan)) { } + : spec(spec) + , plan(std::move(plan)) { } std::vector create_install_plan(const VcpkgPaths& paths, const std::vector& specs, const StatusParagraphs& status_db) { std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); - std::unordered_map was_examined; // Examine = we have checked its immediate (non-recursive) dependencies - Graphs::Graph graph; - graph.add_vertices(specs); - - std::vector examine_stack(specs); - while (!examine_stack.empty()) + struct InstallAdjacencyProvider final : Graphs::AdjacencyProvider { - const PackageSpec spec = examine_stack.back(); - examine_stack.pop_back(); - - if (was_examined.find(spec) != was_examined.end()) - { - continue; - } + const VcpkgPaths& paths; + const StatusParagraphs& status_db; - auto process_dependencies = [&](const std::vector& dependencies_as_string) - { - for (const std::string& dep_as_string : dependencies_as_string) - { - const PackageSpec current_dep = PackageSpec::from_name_and_triplet(dep_as_string, spec.triplet()).value_or_exit(VCPKG_LINE_INFO); - auto it = status_db.find_installed(current_dep); - if (it != status_db.end()) - { - continue; - } - - graph.add_edge(spec, current_dep); - if (was_examined.find(current_dep) == was_examined.end()) - { - examine_stack.push_back(std::move(current_dep)); - } - } - }; + InstallAdjacencyProvider(const VcpkgPaths& p, const StatusParagraphs & s) : paths(p) + , status_db(s) {} - const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end() ? RequestType::USER_REQUESTED : RequestType::AUTO_SELECTED; - auto it = status_db.find_installed(spec); - if (it != status_db.end()) + std::vector adjacency_list(const AnyParagraph& p) const override { - was_examined.emplace(spec, InstallPlanAction{ InstallPlanType::ALREADY_INSTALLED, request_type, nullopt, nullopt }); - continue; + if (p.status_paragraph.get()) + return std::vector{}; + return p.edges(); } - Expected maybe_bpgh = Paragraphs::try_load_cached_package(paths, spec); - if (BinaryParagraph* bpgh = maybe_bpgh.get()) + AnyParagraph load_vertex_data(const PackageSpec& spec) const override { - process_dependencies(bpgh->depends); - was_examined.emplace(spec, InstallPlanAction{ InstallPlanType::INSTALL, request_type, std::move(*bpgh), nullopt }); - continue; - } + auto it = status_db.find_installed(spec); + if (it != status_db.end()) + return { spec, *it->get(), nullopt, nullopt }; - Expected maybe_spgh = Paragraphs::try_load_port(paths.port_dir(spec)); - if (auto spgh = maybe_spgh.get()) - { - process_dependencies(filter_dependencies(spgh->depends, spec.triplet())); - was_examined.emplace(spec, InstallPlanAction{ InstallPlanType::BUILD_AND_INSTALL, request_type, nullopt, std::move(*spgh) }); - } - else - { - Checks::exit_with_message(VCPKG_LINE_INFO, "Cannot find package %s", spec.name()); + Expected maybe_bpgh = Paragraphs::try_load_cached_package(paths, spec); + if (auto bpgh = maybe_bpgh.get()) + return { spec, nullopt, *bpgh, nullopt }; + + Expected maybe_spgh = Paragraphs::try_load_port(paths.port_dir(spec)); + if (auto spgh = maybe_spgh.get()) + return { spec, nullopt, nullopt, *spgh }; + + return { spec , nullopt, nullopt, nullopt }; } - } + }; - std::vector ret; + auto toposort = Graphs::topological_sort(specs, InstallAdjacencyProvider{ paths, status_db }); - const std::vector pkgs = graph.topological_sort(); - for (const PackageSpec& pkg : pkgs) + std::vector ret; + for (const AnyParagraph& pkg : toposort) { - ret.push_back(PackageSpecWithInstallPlan(pkg, std::move(was_examined[pkg]))); + auto spec = pkg.spec; + const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end() ? RequestType::USER_REQUESTED : RequestType::AUTO_SELECTED; + if (pkg.status_paragraph && request_type != RequestType::USER_REQUESTED) + continue; + InstallPlanAction a(pkg, request_type); + ret.push_back(PackageSpecWithInstallPlan(spec, std::move(a))); } return ret; } -- cgit v1.2.3 From 6ef84f8a629d3a1578bedb7c02596e81a5e8714b Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 12 Apr 2017 16:11:31 -0700 Subject: Add default constructor to Optional --- toolsrc/include/vcpkg_optional.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/toolsrc/include/vcpkg_optional.h b/toolsrc/include/vcpkg_optional.h index 4a2ceec30..28bdc81fa 100644 --- a/toolsrc/include/vcpkg_optional.h +++ b/toolsrc/include/vcpkg_optional.h @@ -15,6 +15,8 @@ namespace vcpkg class Optional { public: + constexpr Optional() : m_is_present(false), m_t() { } + // Constructors are intentionally implicit constexpr Optional(NullOpt) : m_is_present(false), m_t() { } -- cgit v1.2.3 From ea42d5c686bb5d404c42045491052347bbfdcdd6 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 12 Apr 2017 16:15:16 -0700 Subject: Remove repeated #include --- toolsrc/src/StatusParagraphs.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/toolsrc/src/StatusParagraphs.cpp b/toolsrc/src/StatusParagraphs.cpp index 59e6ee331..7d09b30e9 100644 --- a/toolsrc/src/StatusParagraphs.cpp +++ b/toolsrc/src/StatusParagraphs.cpp @@ -2,8 +2,6 @@ #include "StatusParagraphs.h" #include "vcpkg_Checks.h" #include -#include -#include namespace vcpkg { -- cgit v1.2.3 From 5afcd0afe0484ecb646e4c17f0d38814eba34065 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 12 Apr 2017 16:16:57 -0700 Subject: Use status_db.find_installed() --- toolsrc/src/vcpkg_Dependencies.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index 3a53c42d1..6e22c8b82 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -183,8 +183,8 @@ namespace vcpkg::Dependencies continue; } - const StatusParagraphs::const_iterator it = status_db.find(spec); - if (it == status_db.end() || (*it)->state == InstallState::NOT_INSTALLED) + const StatusParagraphs::const_iterator it = status_db.find_installed(spec); + if (it == status_db.end()) { was_examined.emplace(spec, RemovePlanAction(RemovePlanType::NOT_INSTALLED, RequestType::USER_REQUESTED)); continue; -- cgit v1.2.3 From 88e0246c771d5910fc23849a451510159b85aca7 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 12 Apr 2017 16:19:52 -0700 Subject: Improve create_remove_plan (still using Graph) --- toolsrc/src/vcpkg_Dependencies.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index 6e22c8b82..b714abdae 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -190,10 +190,9 @@ namespace vcpkg::Dependencies continue; } - for (const std::unique_ptr& an_installed_package : status_db) + const std::vector installed_ports = get_installed_ports(status_db); + for (const StatusParagraph* an_installed_package : installed_ports) { - if (an_installed_package->want != Want::INSTALL) - continue; if (an_installed_package->package.spec.triplet() != spec.triplet()) continue; @@ -203,8 +202,8 @@ namespace vcpkg::Dependencies continue; } - graph.add_edge(spec, an_installed_package.get()->package.spec); - examine_stack.push_back(an_installed_package.get()->package.spec); + graph.add_edge(spec, an_installed_package->package.spec); + examine_stack.push_back(an_installed_package->package.spec); } const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end() ? RequestType::USER_REQUESTED : RequestType::AUTO_SELECTED; -- cgit v1.2.3 From 4749d7d67d43ac3c7c1c743eb838962c418f0d14 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 12 Apr 2017 16:24:49 -0700 Subject: Move line below temp struct --- toolsrc/src/vcpkg_Dependencies.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index b714abdae..4c0254ae4 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -114,8 +114,6 @@ namespace vcpkg::Dependencies std::vector create_install_plan(const VcpkgPaths& paths, const std::vector& specs, const StatusParagraphs& status_db) { - std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); - struct InstallAdjacencyProvider final : Graphs::AdjacencyProvider { const VcpkgPaths& paths; @@ -151,6 +149,7 @@ namespace vcpkg::Dependencies auto toposort = Graphs::topological_sort(specs, InstallAdjacencyProvider{ paths, status_db }); + std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); std::vector ret; for (const AnyParagraph& pkg : toposort) { -- cgit v1.2.3 From 7f79f44b0c7084a80af541db04c54f3d1e95316c Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 12 Apr 2017 18:55:37 -0700 Subject: Rework create_install_plan() --- toolsrc/src/vcpkg_Dependencies.cpp | 90 +++++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 39 deletions(-) diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index 4c0254ae4..a2d7dcc7f 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -6,6 +6,7 @@ #include "StatusParagraphs.h" #include "vcpkg_Files.h" #include "vcpkg_Util.h" +#include "vcpkglib.h" namespace vcpkg::Dependencies { @@ -119,7 +120,7 @@ namespace vcpkg::Dependencies const VcpkgPaths& paths; const StatusParagraphs& status_db; - InstallAdjacencyProvider(const VcpkgPaths& p, const StatusParagraphs & s) : paths(p) + InstallAdjacencyProvider(const VcpkgPaths& p, const StatusParagraphs& s) : paths(p) , status_db(s) {} std::vector adjacency_list(const AnyParagraph& p) const override @@ -147,9 +148,9 @@ namespace vcpkg::Dependencies } }; - auto toposort = Graphs::topological_sort(specs, InstallAdjacencyProvider{ paths, status_db }); + const std::vector toposort = Graphs::topological_sort(specs, InstallAdjacencyProvider{ paths, status_db }); - std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); + const std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); std::vector ret; for (const AnyParagraph& pkg : toposort) { @@ -163,58 +164,69 @@ namespace vcpkg::Dependencies return ret; } - std::vector create_remove_plan(const std::vector& specs, const StatusParagraphs& status_db) + struct SpecAndRemovePlanType { - std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); - - std::unordered_map was_examined; // Examine = we have checked its immediate (non-recursive) dependencies - Graphs::Graph graph; - graph.add_vertices(specs); + PackageSpec spec; + RemovePlanType plan_type; + }; - std::vector examine_stack(specs); - while (!examine_stack.empty()) + std::vector create_remove_plan(const std::vector& specs, const StatusParagraphs& status_db) + { + struct RemoveAdjacencyProvider final : Graphs::AdjacencyProvider { - const PackageSpec spec = examine_stack.back(); - examine_stack.pop_back(); + const StatusParagraphs& status_db; + const std::vector& installed_ports; - if (was_examined.find(spec) != was_examined.end()) - { - continue; - } + RemoveAdjacencyProvider(const StatusParagraphs& status_db, const std::vector& installed_ports) + : status_db(status_db) + , installed_ports(installed_ports) { } - const StatusParagraphs::const_iterator it = status_db.find_installed(spec); - if (it == status_db.end()) + std::vector adjacency_list(const SpecAndRemovePlanType& p) const override { - was_examined.emplace(spec, RemovePlanAction(RemovePlanType::NOT_INSTALLED, RequestType::USER_REQUESTED)); - continue; + if (p.plan_type == RemovePlanType::NOT_INSTALLED) + { + return {}; + } + + const PackageSpec& spec = p.spec; + std::vector dependents; + for (const StatusParagraph* an_installed_package : installed_ports) + { + if (an_installed_package->package.spec.triplet() != spec.triplet()) + continue; + + const std::vector& deps = an_installed_package->package.depends; + if (std::find(deps.begin(), deps.end(), spec.name()) == deps.end()) + continue; + + dependents.push_back(an_installed_package->package.spec); + } + + return dependents; } - const std::vector installed_ports = get_installed_ports(status_db); - for (const StatusParagraph* an_installed_package : installed_ports) + SpecAndRemovePlanType load_vertex_data(const PackageSpec& spec) const override { - if (an_installed_package->package.spec.triplet() != spec.triplet()) - continue; - - const std::vector& deps = an_installed_package->package.depends; - if (std::find(deps.begin(), deps.end(), spec.name()) == deps.end()) + const StatusParagraphs::const_iterator it = status_db.find_installed(spec); + if (it == status_db.end()) { - continue; + return {spec, RemovePlanType::NOT_INSTALLED}; } - - graph.add_edge(spec, an_installed_package->package.spec); - examine_stack.push_back(an_installed_package->package.spec); + return { spec, RemovePlanType::REMOVE }; } + }; - const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end() ? RequestType::USER_REQUESTED : RequestType::AUTO_SELECTED; - was_examined.emplace(spec, RemovePlanAction(RemovePlanType::REMOVE, request_type)); - } + const std::vector& installed_ports = get_installed_ports(status_db); + const std::vector toposort = Graphs::topological_sort(specs, RemoveAdjacencyProvider{ status_db, installed_ports }); + const std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); std::vector ret; - - const std::vector pkgs = graph.topological_sort(); - for (const PackageSpec& pkg : pkgs) + for (const SpecAndRemovePlanType& pkg : toposort) { - ret.push_back(PackageSpecWithRemovePlan(pkg, std::move(was_examined[pkg]))); + auto spec = pkg.spec; + const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end() ? RequestType::USER_REQUESTED : RequestType::AUTO_SELECTED; + RemovePlanAction r(pkg.plan_type, request_type); + ret.push_back(PackageSpecWithRemovePlan(spec, std::move(r))); } return ret; } -- cgit v1.2.3 From 2cc01b2acac847533e931a0c89cd7117756022fc Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 12 Apr 2017 18:56:41 -0700 Subject: Remove Graph class --- toolsrc/include/vcpkg_Graphs.h | 92 ------------------------------------------ 1 file changed, 92 deletions(-) diff --git a/toolsrc/include/vcpkg_Graphs.h b/toolsrc/include/vcpkg_Graphs.h index 8af2ad053..1b9cbcb5a 100644 --- a/toolsrc/include/vcpkg_Graphs.h +++ b/toolsrc/include/vcpkg_Graphs.h @@ -1,7 +1,6 @@ #pragma once #include -#include namespace vcpkg::Graphs { @@ -67,95 +66,4 @@ namespace vcpkg::Graphs return sorted; } - - template - struct GraphAdjacencyProvider final : AdjacencyProvider - { - const std::unordered_map>& vertices; - - GraphAdjacencyProvider(const std::unordered_map>& vertices) : vertices(vertices) {} - - std::vector adjacency_list(const V& vertex) const override - { - const std::unordered_set& as_set = this->vertices.at(vertex); - return std::vector(as_set.cbegin(), as_set.cend()); // TODO: Avoid redundant copy - } - - V load_vertex_data(const V& vertex) const override - { - return vertex; - } - }; - - template - class Graph - { - public: - void add_vertex(V v) - { - this->vertices[v]; - } - - // TODO: Change with iterators - void add_vertices(const std::vector& vs) - { - for (const V& v : vs) - { - this->vertices[v]; - } - } - - void add_edge(V u, V v) - { - this->vertices[v]; - this->vertices[u].insert(v); - } - - std::vector topological_sort() const - { - GraphAdjacencyProvider adjacency_provider{ this->vertices }; - std::unordered_map indegrees = count_indegrees(); - - std::vector sorted; - sorted.reserve(indegrees.size()); - - std::unordered_map exploration_status; - exploration_status.reserve(indegrees.size()); - - for (auto& pair : indegrees) - { - if (pair.second == 0) // Starting from vertices with indegree == 0. Not required. - { - V vertex = pair.first; - topological_sort_internal(vertex, adjacency_provider, exploration_status, sorted); - } - } - - return sorted; - } - - std::unordered_map count_indegrees() const - { - std::unordered_map indegrees; - - for (auto& pair : this->vertices) - { - indegrees[pair.first]; - for (V neighbour : pair.second) - { - ++indegrees[neighbour]; - } - } - - return indegrees; - } - - const std::unordered_map>& adjacency_list() const - { - return this->vertices; - } - - private: - std::unordered_map> vertices; - }; } -- cgit v1.2.3 From 5cd921c2b55340d2d300250537de5600b48a2b12 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 12 Apr 2017 18:57:45 -0700 Subject: edges() -> dependencies() --- toolsrc/include/vcpkg_Dependencies.h | 3 +-- toolsrc/src/vcpkg_Dependencies.cpp | 5 +++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/toolsrc/include/vcpkg_Dependencies.h b/toolsrc/include/vcpkg_Dependencies.h index 36dd3cb2d..47cbb6da3 100644 --- a/toolsrc/include/vcpkg_Dependencies.h +++ b/toolsrc/include/vcpkg_Dependencies.h @@ -4,13 +4,12 @@ #include "StatusParagraphs.h" #include "VcpkgPaths.h" #include "vcpkg_optional.h" -#include "Paragraphs.h" namespace vcpkg::Dependencies { struct AnyParagraph { - std::vector edges() const; + std::vector dependencies() const; PackageSpec spec; Optional status_paragraph; diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index a2d7dcc7f..565d6114c 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -7,10 +7,11 @@ #include "vcpkg_Files.h" #include "vcpkg_Util.h" #include "vcpkglib.h" +#include "Paragraphs.h" namespace vcpkg::Dependencies { - std::vector AnyParagraph::edges() const + std::vector AnyParagraph::dependencies() const { auto to_package_specs = [&](const std::vector& dependencies_as_string) { @@ -127,7 +128,7 @@ namespace vcpkg::Dependencies { if (p.status_paragraph.get()) return std::vector{}; - return p.edges(); + return p.dependencies(); } AnyParagraph load_vertex_data(const PackageSpec& spec) const override -- cgit v1.2.3 From 76f2c557ef915a13b37bc9a3ff0f9299373fe923 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 12 Apr 2017 19:29:43 -0700 Subject: Fix issue in the toposort algorithm and move-only types --- toolsrc/include/vcpkg_Graphs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolsrc/include/vcpkg_Graphs.h b/toolsrc/include/vcpkg_Graphs.h index 1b9cbcb5a..97cd29236 100644 --- a/toolsrc/include/vcpkg_Graphs.h +++ b/toolsrc/include/vcpkg_Graphs.h @@ -40,7 +40,7 @@ namespace vcpkg::Graphs case ExplorationStatus::NOT_EXPLORED: { status = ExplorationStatus::PARTIALLY_EXPLORED; - const U& vertex_data = f.load_vertex_data(vertex); + U vertex_data = f.load_vertex_data(vertex); for (const V& neighbour : f.adjacency_list(vertex_data)) topological_sort_internal(neighbour, f, exploration_status, sorted); -- cgit v1.2.3 From 5131e955a809b421345506cd614c8578ab86fa71 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 12 Apr 2017 21:28:49 -0700 Subject: Simplify Install plan generation --- toolsrc/include/vcpkg_Dependencies.h | 30 ++++++------- toolsrc/src/commands_build.cpp | 10 ++--- toolsrc/src/commands_ci.cpp | 12 ++--- toolsrc/src/commands_install.cpp | 36 +++++++-------- toolsrc/src/vcpkg_Dependencies.cpp | 87 +++++++++++++----------------------- 5 files changed, 74 insertions(+), 101 deletions(-) diff --git a/toolsrc/include/vcpkg_Dependencies.h b/toolsrc/include/vcpkg_Dependencies.h index 47cbb6da3..155fb12e6 100644 --- a/toolsrc/include/vcpkg_Dependencies.h +++ b/toolsrc/include/vcpkg_Dependencies.h @@ -9,9 +9,8 @@ namespace vcpkg::Dependencies { struct AnyParagraph { - std::vector dependencies() const; + std::vector dependencies(const Triplet& triplet) const; - PackageSpec spec; Optional status_paragraph; Optional binary_paragraph; Optional source_paragraph; @@ -36,28 +35,19 @@ namespace vcpkg::Dependencies struct InstallPlanAction { + static bool compare_by_name(const InstallPlanAction* left, const InstallPlanAction* right); + InstallPlanAction(); - explicit InstallPlanAction(const AnyParagraph& any_paragraph, const RequestType& request_type); - InstallPlanAction(const InstallPlanType& plan_type, const RequestType& request_type, Optional binary_pgh, Optional source_pgh); + explicit InstallPlanAction(const PackageSpec& spec, const AnyParagraph& any_paragraph, const RequestType& request_type); InstallPlanAction(const InstallPlanAction&) = delete; InstallPlanAction(InstallPlanAction&&) = default; InstallPlanAction& operator=(const InstallPlanAction&) = delete; InstallPlanAction& operator=(InstallPlanAction&&) = default; + PackageSpec spec; + AnyParagraph any_paragraph; InstallPlanType plan_type; RequestType request_type; - Optional binary_pgh; - Optional source_pgh; - }; - - struct PackageSpecWithInstallPlan - { - static bool compare_by_name(const PackageSpecWithInstallPlan* left, const PackageSpecWithInstallPlan* right); - - PackageSpecWithInstallPlan(const PackageSpec& spec, InstallPlanAction&& plan); - - PackageSpec spec; - InstallPlanAction plan; }; enum class RemovePlanType @@ -67,6 +57,12 @@ namespace vcpkg::Dependencies REMOVE }; + struct SpecAndRemovePlanType + { + PackageSpec spec; + RemovePlanType plan_type; + }; + struct RemovePlanAction { RemovePlanAction(); @@ -90,7 +86,7 @@ namespace vcpkg::Dependencies RemovePlanAction plan; }; - std::vector create_install_plan(const VcpkgPaths& paths, const std::vector& specs, const StatusParagraphs& status_db); + std::vector create_install_plan(const VcpkgPaths& paths, const std::vector& specs, const StatusParagraphs& status_db); std::vector create_remove_plan(const std::vector& specs, const StatusParagraphs& status_db); } diff --git a/toolsrc/src/commands_build.cpp b/toolsrc/src/commands_build.cpp index 96b0b0346..c3ebd7de8 100644 --- a/toolsrc/src/commands_build.cpp +++ b/toolsrc/src/commands_build.cpp @@ -13,7 +13,7 @@ namespace vcpkg::Commands::Build { - using Dependencies::PackageSpecWithInstallPlan; + using Dependencies::InstallPlanAction; using Dependencies::InstallPlanType; static const std::string OPTION_CHECKS_ONLY = "--checks-only"; @@ -148,11 +148,11 @@ namespace vcpkg::Commands::Build const BuildResult result = build_package(spgh, spec, paths, paths.port_dir(spec), status_db); if (result == BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES) { - std::vector unmet_dependencies = Dependencies::create_install_plan(paths, { spec }, status_db); + std::vector unmet_dependencies = Dependencies::create_install_plan(paths, { spec }, status_db); unmet_dependencies.erase( - std::remove_if(unmet_dependencies.begin(), unmet_dependencies.end(), [&spec](const PackageSpecWithInstallPlan& p) + std::remove_if(unmet_dependencies.begin(), unmet_dependencies.end(), [&spec](const InstallPlanAction& p) { - return (p.spec == spec) || (p.plan.plan_type == InstallPlanType::ALREADY_INSTALLED); + return (p.spec == spec) || (p.plan_type == InstallPlanType::ALREADY_INSTALLED); }), unmet_dependencies.end()); @@ -160,7 +160,7 @@ namespace vcpkg::Commands::Build System::println(System::Color::error, "The build command requires all dependencies to be already installed."); System::println("The following dependencies are missing:"); System::println(""); - for (const PackageSpecWithInstallPlan& p : unmet_dependencies) + for (const InstallPlanAction& p : unmet_dependencies) { System::println(" %s", p.spec); } diff --git a/toolsrc/src/commands_ci.cpp b/toolsrc/src/commands_ci.cpp index 0e095d085..6c6cd8751 100644 --- a/toolsrc/src/commands_ci.cpp +++ b/toolsrc/src/commands_ci.cpp @@ -10,7 +10,7 @@ namespace vcpkg::Commands::CI { - using Dependencies::PackageSpecWithInstallPlan; + using Dependencies::InstallPlanAction; using Dependencies::InstallPlanType; using Build::BuildResult; @@ -36,7 +36,7 @@ namespace vcpkg::Commands::CI const std::vector specs = load_all_package_specs(paths.ports, triplet); StatusParagraphs status_db = database_load_check(paths); - const std::vector install_plan = Dependencies::create_install_plan(paths, specs, status_db); + const std::vector install_plan = Dependencies::create_install_plan(paths, specs, status_db); Checks::check_exit(VCPKG_LINE_INFO, !install_plan.empty(), "Install plan cannot be empty"); std::vector results; @@ -44,7 +44,7 @@ namespace vcpkg::Commands::CI const ElapsedTime timer = ElapsedTime::create_started(); size_t counter = 0; const size_t package_count = install_plan.size(); - for (const PackageSpecWithInstallPlan& action : install_plan) + for (const InstallPlanAction& action : install_plan) { const ElapsedTime build_timer = ElapsedTime::create_started(); counter++; @@ -56,7 +56,7 @@ namespace vcpkg::Commands::CI try { - switch (action.plan.plan_type) + switch (action.plan_type) { case InstallPlanType::ALREADY_INSTALLED: results.back() = BuildResult::SUCCEEDED; @@ -65,7 +65,7 @@ namespace vcpkg::Commands::CI case InstallPlanType::BUILD_AND_INSTALL: { System::println("Building package %s... ", display_name); - const BuildResult result = Commands::Build::build_package(action.plan.source_pgh.value_or_exit(VCPKG_LINE_INFO), + const BuildResult result = Commands::Build::build_package(action.any_paragraph.source_paragraph.value_or_exit(VCPKG_LINE_INFO), action.spec, paths, paths.port_dir(action.spec), @@ -88,7 +88,7 @@ namespace vcpkg::Commands::CI case InstallPlanType::INSTALL: results.back() = BuildResult::SUCCEEDED; System::println("Installing package %s... ", display_name); - Install::install_package(paths, action.plan.binary_pgh.value_or_exit(VCPKG_LINE_INFO), &status_db); + Install::install_package(paths, action.any_paragraph.binary_paragraph.value_or_exit(VCPKG_LINE_INFO), &status_db); System::println(System::Color::success, "Installing package %s... done", display_name); break; default: diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/commands_install.cpp index f3da36fa0..034a4c88e 100644 --- a/toolsrc/src/commands_install.cpp +++ b/toolsrc/src/commands_install.cpp @@ -11,7 +11,7 @@ namespace vcpkg::Commands::Install { - using Dependencies::PackageSpecWithInstallPlan; + using Dependencies::InstallPlanAction; using Dependencies::RequestType; using Dependencies::InstallPlanType; @@ -138,15 +138,15 @@ namespace vcpkg::Commands::Install return SortedVector(std::move(installed_files)); } - static void print_plan(const std::vector& plan) + static void print_plan(const std::vector& plan) { - std::vector already_installed; - std::vector build_and_install; - std::vector install; + std::vector already_installed; + std::vector build_and_install; + std::vector install; - for (const PackageSpecWithInstallPlan& i : plan) + for (const InstallPlanAction& i : plan) { - switch (i.plan.plan_type) + switch (i.plan_type) { case InstallPlanType::ALREADY_INSTALLED: already_installed.push_back(&i); @@ -162,23 +162,23 @@ namespace vcpkg::Commands::Install } } - auto print_lambda = [](const PackageSpecWithInstallPlan* p) { return to_output_string(p->plan.request_type, p->spec.to_string()); }; + auto print_lambda = [](const InstallPlanAction* p) { return Dependencies::to_output_string(p->request_type, p->spec.to_string()); }; if (!already_installed.empty()) { - std::sort(already_installed.begin(), already_installed.end(), &PackageSpecWithInstallPlan::compare_by_name); + std::sort(already_installed.begin(), already_installed.end(), &InstallPlanAction::compare_by_name); System::println("The following packages are already installed:\n%s", Strings::join("\n", already_installed, print_lambda)); } if (!build_and_install.empty()) { - std::sort(build_and_install.begin(), build_and_install.end(), &PackageSpecWithInstallPlan::compare_by_name); + std::sort(build_and_install.begin(), build_and_install.end(), &InstallPlanAction::compare_by_name); System::println("The following packages will be built and installed:\n%s", Strings::join("\n", build_and_install, print_lambda)); } if (!install.empty()) { - std::sort(install.begin(), install.end(), &PackageSpecWithInstallPlan::compare_by_name); + std::sort(install.begin(), install.end(), &InstallPlanAction::compare_by_name); System::println("The following packages will be installed:\n%s", Strings::join("\n", install, print_lambda)); } } @@ -250,7 +250,7 @@ namespace vcpkg::Commands::Install // create the plan StatusParagraphs status_db = database_load_check(paths); - std::vector install_plan = Dependencies::create_install_plan(paths, specs, status_db); + std::vector install_plan = Dependencies::create_install_plan(paths, specs, status_db); Checks::check_exit(VCPKG_LINE_INFO, !install_plan.empty(), "Install plan cannot be empty"); // log the plan @@ -264,9 +264,9 @@ namespace vcpkg::Commands::Install print_plan(install_plan); - const bool has_non_user_requested_packages = std::find_if(install_plan.cbegin(), install_plan.cend(), [](const PackageSpecWithInstallPlan& package)-> bool + const bool has_non_user_requested_packages = std::find_if(install_plan.cbegin(), install_plan.cend(), [](const InstallPlanAction& package)-> bool { - return package.plan.request_type != RequestType::USER_REQUESTED; + return package.request_type != RequestType::USER_REQUESTED; }) != install_plan.cend(); if (has_non_user_requested_packages) @@ -280,13 +280,13 @@ namespace vcpkg::Commands::Install } // execute the plan - for (const PackageSpecWithInstallPlan& action : install_plan) + for (const InstallPlanAction& action : install_plan) { const std::string display_name = action.spec.to_string(); try { - switch (action.plan.plan_type) + switch (action.plan_type) { case InstallPlanType::ALREADY_INSTALLED: System::println(System::Color::success, "Package %s is already installed", display_name); @@ -294,7 +294,7 @@ namespace vcpkg::Commands::Install case InstallPlanType::BUILD_AND_INSTALL: { System::println("Building package %s... ", display_name); - const Build::BuildResult result = Commands::Build::build_package(action.plan.source_pgh.value_or_exit(VCPKG_LINE_INFO), + const Build::BuildResult result = Commands::Build::build_package(action.any_paragraph.source_paragraph.value_or_exit(VCPKG_LINE_INFO), action.spec, paths, paths.port_dir(action.spec), @@ -315,7 +315,7 @@ namespace vcpkg::Commands::Install } case InstallPlanType::INSTALL: System::println("Installing package %s... ", display_name); - install_package(paths, action.plan.binary_pgh.value_or_exit(VCPKG_LINE_INFO), &status_db); + install_package(paths, action.any_paragraph.binary_paragraph.value_or_exit(VCPKG_LINE_INFO), &status_db); System::println(System::Color::success, "Installing package %s... done", display_name); break; case InstallPlanType::UNKNOWN: diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index 565d6114c..c893f884d 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -11,13 +11,13 @@ namespace vcpkg::Dependencies { - std::vector AnyParagraph::dependencies() const + std::vector AnyParagraph::dependencies(const Triplet& triplet) const { auto to_package_specs = [&](const std::vector& dependencies_as_string) { return Util::fmap(dependencies_as_string, [&](const std::string s) { - return PackageSpec::from_name_and_triplet(s, this->spec.triplet()).value_or_exit(VCPKG_LINE_INFO); + return PackageSpec::from_name_and_triplet(s, triplet).value_or_exit(VCPKG_LINE_INFO); }); }; @@ -33,10 +33,10 @@ namespace vcpkg::Dependencies if (auto p = this->source_paragraph.get()) { - return to_package_specs(filter_dependencies(p->depends, this->spec.triplet())); + return to_package_specs(filter_dependencies(p->depends, triplet)); } - Checks::exit_with_message(VCPKG_LINE_INFO, "Cannot get dependencies for package %s because there was none of: source/binary/status paragraphs", spec.to_string()); + Checks::exit_with_message(VCPKG_LINE_INFO, "Cannot get dependencies because there was none of: source/binary/status paragraphs"); } std::string to_output_string(RequestType request_type, const CStringView s) @@ -52,52 +52,44 @@ namespace vcpkg::Dependencies } } - InstallPlanAction::InstallPlanAction() : plan_type(InstallPlanType::UNKNOWN) - , request_type(RequestType::UNKNOWN) - , binary_pgh(nullopt) - , source_pgh(nullopt) { } + InstallPlanAction::InstallPlanAction() : spec() + , any_paragraph() + , plan_type(InstallPlanType::UNKNOWN) + , request_type(RequestType::UNKNOWN) { } - InstallPlanAction::InstallPlanAction(const AnyParagraph& any_paragraph, const RequestType& request_type) : InstallPlanAction() + InstallPlanAction::InstallPlanAction(const PackageSpec& spec, const AnyParagraph& any_paragraph, const RequestType& request_type) : InstallPlanAction() { + this->spec = spec; this->request_type = request_type; - if (any_paragraph.status_paragraph.get()) + if (auto p = any_paragraph.status_paragraph.get()) { this->plan_type = InstallPlanType::ALREADY_INSTALLED; + this->any_paragraph.status_paragraph = *p; return; } if (auto p = any_paragraph.binary_paragraph.get()) { this->plan_type = InstallPlanType::INSTALL; - this->binary_pgh = *p; + this->any_paragraph.binary_paragraph = *p; return; } if (auto p = any_paragraph.source_paragraph.get()) { this->plan_type = InstallPlanType::BUILD_AND_INSTALL; - this->source_pgh = *p; + this->any_paragraph.source_paragraph = *p; return; } this->plan_type = InstallPlanType::UNKNOWN; } - InstallPlanAction::InstallPlanAction(const InstallPlanType& plan_type, const RequestType& request_type, Optional binary_pgh, Optional source_pgh) - : plan_type(std::move(plan_type)) - , request_type(request_type) - , binary_pgh(std::move(binary_pgh)) - , source_pgh(std::move(source_pgh)) { } - - bool PackageSpecWithInstallPlan::compare_by_name(const PackageSpecWithInstallPlan* left, const PackageSpecWithInstallPlan* right) + bool InstallPlanAction::compare_by_name(const InstallPlanAction* left, const InstallPlanAction* right) { return left->spec.name() < right->spec.name(); } - PackageSpecWithInstallPlan::PackageSpecWithInstallPlan(const PackageSpec& spec, InstallPlanAction&& plan) - : spec(spec) - , plan(std::move(plan)) { } - RemovePlanAction::RemovePlanAction() : plan_type(RemovePlanType::UNKNOWN) , request_type(RequestType::UNKNOWN) { } @@ -114,63 +106,48 @@ namespace vcpkg::Dependencies : spec(spec) , plan(std::move(plan)) { } - std::vector create_install_plan(const VcpkgPaths& paths, const std::vector& specs, const StatusParagraphs& status_db) + std::vector create_install_plan(const VcpkgPaths& paths, const std::vector& specs, const StatusParagraphs& status_db) { - struct InstallAdjacencyProvider final : Graphs::AdjacencyProvider + struct InstallAdjacencyProvider final : Graphs::AdjacencyProvider { const VcpkgPaths& paths; const StatusParagraphs& status_db; + const std::unordered_set& specs_as_set; - InstallAdjacencyProvider(const VcpkgPaths& p, const StatusParagraphs& s) : paths(p) - , status_db(s) {} + InstallAdjacencyProvider(const VcpkgPaths& p, const StatusParagraphs& s, const std::unordered_set& specs_as_set) : paths(p) + , status_db(s) + , specs_as_set(specs_as_set) {} - std::vector adjacency_list(const AnyParagraph& p) const override + std::vector adjacency_list(const InstallPlanAction& p) const override { - if (p.status_paragraph.get()) + if (p.any_paragraph.status_paragraph.get()) return std::vector{}; - return p.dependencies(); + return p.any_paragraph.dependencies(p.spec.triplet()); } - AnyParagraph load_vertex_data(const PackageSpec& spec) const override + InstallPlanAction load_vertex_data(const PackageSpec& spec) const override { + const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end() ? RequestType::USER_REQUESTED : RequestType::AUTO_SELECTED; auto it = status_db.find_installed(spec); if (it != status_db.end()) - return { spec, *it->get(), nullopt, nullopt }; + return InstallPlanAction{ spec, { *it->get(), nullopt, nullopt }, request_type }; Expected maybe_bpgh = Paragraphs::try_load_cached_package(paths, spec); if (auto bpgh = maybe_bpgh.get()) - return { spec, nullopt, *bpgh, nullopt }; + return InstallPlanAction{ spec, {nullopt, *bpgh, nullopt}, request_type }; Expected maybe_spgh = Paragraphs::try_load_port(paths.port_dir(spec)); if (auto spgh = maybe_spgh.get()) - return { spec, nullopt, nullopt, *spgh }; + return InstallPlanAction{ spec, {nullopt, nullopt, *spgh}, request_type }; - return { spec , nullopt, nullopt, nullopt }; + return InstallPlanAction{ spec , {nullopt, nullopt, nullopt}, request_type }; } }; - const std::vector toposort = Graphs::topological_sort(specs, InstallAdjacencyProvider{ paths, status_db }); - const std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); - std::vector ret; - for (const AnyParagraph& pkg : toposort) - { - auto spec = pkg.spec; - const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end() ? RequestType::USER_REQUESTED : RequestType::AUTO_SELECTED; - if (pkg.status_paragraph && request_type != RequestType::USER_REQUESTED) - continue; - InstallPlanAction a(pkg, request_type); - ret.push_back(PackageSpecWithInstallPlan(spec, std::move(a))); - } - return ret; + return Graphs::topological_sort(specs, InstallAdjacencyProvider{ paths, status_db, specs_as_set }); } - struct SpecAndRemovePlanType - { - PackageSpec spec; - RemovePlanType plan_type; - }; - std::vector create_remove_plan(const std::vector& specs, const StatusParagraphs& status_db) { struct RemoveAdjacencyProvider final : Graphs::AdjacencyProvider @@ -211,7 +188,7 @@ namespace vcpkg::Dependencies const StatusParagraphs::const_iterator it = status_db.find_installed(spec); if (it == status_db.end()) { - return {spec, RemovePlanType::NOT_INSTALLED}; + return { spec, RemovePlanType::NOT_INSTALLED }; } return { spec, RemovePlanType::REMOVE }; } -- cgit v1.2.3 From 2fa87fbb0aba1eba96994beb0c7b32d52f7f7161 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 12 Apr 2017 21:37:55 -0700 Subject: Simplify Remove plan generation --- toolsrc/include/vcpkg_Dependencies.h | 41 +++++++++++------------------- toolsrc/src/commands_remove.cpp | 28 ++++++++++----------- toolsrc/src/vcpkg_Dependencies.cpp | 48 ++++++++++++++---------------------- 3 files changed, 47 insertions(+), 70 deletions(-) diff --git a/toolsrc/include/vcpkg_Dependencies.h b/toolsrc/include/vcpkg_Dependencies.h index 155fb12e6..f35250447 100644 --- a/toolsrc/include/vcpkg_Dependencies.h +++ b/toolsrc/include/vcpkg_Dependencies.h @@ -7,15 +7,6 @@ namespace vcpkg::Dependencies { - struct AnyParagraph - { - std::vector dependencies(const Triplet& triplet) const; - - Optional status_paragraph; - Optional binary_paragraph; - Optional source_paragraph; - }; - enum class RequestType { UNKNOWN, @@ -25,6 +16,15 @@ namespace vcpkg::Dependencies std::string to_output_string(RequestType request_type, const CStringView s); + struct AnyParagraph + { + std::vector dependencies(const Triplet& triplet) const; + + Optional status_paragraph; + Optional binary_paragraph; + Optional source_paragraph; + }; + enum class InstallPlanType { UNKNOWN, @@ -57,36 +57,23 @@ namespace vcpkg::Dependencies REMOVE }; - struct SpecAndRemovePlanType - { - PackageSpec spec; - RemovePlanType plan_type; - }; - struct RemovePlanAction { + static bool compare_by_name(const RemovePlanAction* left, const RemovePlanAction* right); + RemovePlanAction(); - RemovePlanAction(const RemovePlanType& plan_type, const RequestType& request_type); + RemovePlanAction(const PackageSpec& spec, const RemovePlanType& plan_type, const RequestType& request_type); RemovePlanAction(const RemovePlanAction&) = delete; RemovePlanAction(RemovePlanAction&&) = default; RemovePlanAction& operator=(const RemovePlanAction&) = delete; RemovePlanAction& operator=(RemovePlanAction&&) = default; + PackageSpec spec; RemovePlanType plan_type; RequestType request_type; }; - struct PackageSpecWithRemovePlan - { - static bool compare_by_name(const PackageSpecWithRemovePlan* left, const PackageSpecWithRemovePlan* right); - - PackageSpecWithRemovePlan(const PackageSpec& spec, RemovePlanAction&& plan); - - PackageSpec spec; - RemovePlanAction plan; - }; - std::vector create_install_plan(const VcpkgPaths& paths, const std::vector& specs, const StatusParagraphs& status_db); - std::vector create_remove_plan(const std::vector& specs, const StatusParagraphs& status_db); + std::vector create_remove_plan(const std::vector& specs, const StatusParagraphs& status_db); } diff --git a/toolsrc/src/commands_remove.cpp b/toolsrc/src/commands_remove.cpp index b26fec36f..52c01f525 100644 --- a/toolsrc/src/commands_remove.cpp +++ b/toolsrc/src/commands_remove.cpp @@ -8,7 +8,7 @@ namespace vcpkg::Commands::Remove { - using Dependencies::PackageSpecWithRemovePlan; + using Dependencies::RemovePlanAction; using Dependencies::RemovePlanType; using Dependencies::RequestType; using Update::OutdatedPackage; @@ -101,14 +101,14 @@ namespace vcpkg::Commands::Remove write_update(paths, pkg); } - static void print_plan(const std::vector& plan) + static void print_plan(const std::vector& plan) { - std::vector not_installed; - std::vector remove; + std::vector not_installed; + std::vector remove; - for (const PackageSpecWithRemovePlan& i : plan) + for (const RemovePlanAction& i : plan) { - switch (i.plan.plan_type) + switch (i.plan_type) { case RemovePlanType::NOT_INSTALLED: not_installed.push_back(&i); @@ -121,17 +121,17 @@ namespace vcpkg::Commands::Remove } } - auto print_lambda = [](const PackageSpecWithRemovePlan* p) { return to_output_string(p->plan.request_type, p->spec.to_string()); }; + auto print_lambda = [](const RemovePlanAction* p) { return Dependencies::to_output_string(p->request_type, p->spec.to_string()); }; if (!not_installed.empty()) { - std::sort(not_installed.begin(), not_installed.end(), &PackageSpecWithRemovePlan::compare_by_name); + std::sort(not_installed.begin(), not_installed.end(), &RemovePlanAction::compare_by_name); System::println("The following packages are not installed, so not removed:\n%s", Strings::join("\n", not_installed, print_lambda)); } if (!remove.empty()) { - std::sort(remove.begin(), remove.end(), &PackageSpecWithRemovePlan::compare_by_name); + std::sort(remove.begin(), remove.end(), &RemovePlanAction::compare_by_name); System::println("The following packages will be removed:\n%s", Strings::join("\n", remove, print_lambda)); } } @@ -172,14 +172,14 @@ namespace vcpkg::Commands::Remove const bool isRecursive = options.find(OPTION_RECURSE) != options.cend(); const bool dryRun = options.find(OPTION_DRY_RUN) != options.cend(); - const std::vector remove_plan = Dependencies::create_remove_plan(specs, status_db); + const std::vector remove_plan = Dependencies::create_remove_plan(specs, status_db); Checks::check_exit(VCPKG_LINE_INFO, !remove_plan.empty(), "Remove plan cannot be empty"); print_plan(remove_plan); - const bool has_non_user_requested_packages = std::find_if(remove_plan.cbegin(), remove_plan.cend(), [](const PackageSpecWithRemovePlan& package)-> bool + const bool has_non_user_requested_packages = std::find_if(remove_plan.cbegin(), remove_plan.cend(), [](const RemovePlanAction& package)-> bool { - return package.plan.request_type != RequestType::USER_REQUESTED; + return package.request_type != RequestType::USER_REQUESTED; }) != remove_plan.cend(); if (has_non_user_requested_packages) @@ -198,11 +198,11 @@ namespace vcpkg::Commands::Remove Checks::exit_success(VCPKG_LINE_INFO); } - for (const PackageSpecWithRemovePlan& action : remove_plan) + for (const RemovePlanAction& action : remove_plan) { const std::string display_name = action.spec.to_string(); - switch (action.plan.plan_type) + switch (action.plan_type) { case RemovePlanType::NOT_INSTALLED: System::println(System::Color::success, "Package %s is not installed", display_name); diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index c893f884d..9952a3f92 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -93,19 +93,16 @@ namespace vcpkg::Dependencies RemovePlanAction::RemovePlanAction() : plan_type(RemovePlanType::UNKNOWN) , request_type(RequestType::UNKNOWN) { } - RemovePlanAction::RemovePlanAction(const RemovePlanType& plan_type, const RequestType& request_type) - : plan_type(plan_type) + RemovePlanAction::RemovePlanAction(const PackageSpec& spec, const RemovePlanType& plan_type, const RequestType& request_type) + : spec(spec) + , plan_type(plan_type) , request_type(request_type) { } - bool PackageSpecWithRemovePlan::compare_by_name(const PackageSpecWithRemovePlan* left, const PackageSpecWithRemovePlan* right) + bool RemovePlanAction::compare_by_name(const RemovePlanAction* left, const RemovePlanAction* right) { return left->spec.name() < right->spec.name(); } - PackageSpecWithRemovePlan::PackageSpecWithRemovePlan(const PackageSpec& spec, RemovePlanAction&& plan) - : spec(spec) - , plan(std::move(plan)) { } - std::vector create_install_plan(const VcpkgPaths& paths, const std::vector& specs, const StatusParagraphs& status_db) { struct InstallAdjacencyProvider final : Graphs::AdjacencyProvider @@ -134,13 +131,13 @@ namespace vcpkg::Dependencies Expected maybe_bpgh = Paragraphs::try_load_cached_package(paths, spec); if (auto bpgh = maybe_bpgh.get()) - return InstallPlanAction{ spec, {nullopt, *bpgh, nullopt}, request_type }; + return InstallPlanAction{ spec, { nullopt, *bpgh, nullopt }, request_type }; Expected maybe_spgh = Paragraphs::try_load_port(paths.port_dir(spec)); if (auto spgh = maybe_spgh.get()) - return InstallPlanAction{ spec, {nullopt, nullopt, *spgh}, request_type }; + return InstallPlanAction{ spec, { nullopt, nullopt, *spgh }, request_type }; - return InstallPlanAction{ spec , {nullopt, nullopt, nullopt}, request_type }; + return InstallPlanAction{ spec , { nullopt, nullopt, nullopt }, request_type }; } }; @@ -148,18 +145,20 @@ namespace vcpkg::Dependencies return Graphs::topological_sort(specs, InstallAdjacencyProvider{ paths, status_db, specs_as_set }); } - std::vector create_remove_plan(const std::vector& specs, const StatusParagraphs& status_db) + std::vector create_remove_plan(const std::vector& specs, const StatusParagraphs& status_db) { - struct RemoveAdjacencyProvider final : Graphs::AdjacencyProvider + struct RemoveAdjacencyProvider final : Graphs::AdjacencyProvider { const StatusParagraphs& status_db; const std::vector& installed_ports; + const std::unordered_set& specs_as_set; - RemoveAdjacencyProvider(const StatusParagraphs& status_db, const std::vector& installed_ports) + RemoveAdjacencyProvider(const StatusParagraphs& status_db, const std::vector& installed_ports, const std::unordered_set& specs_as_set) : status_db(status_db) - , installed_ports(installed_ports) { } + , installed_ports(installed_ports) + , specs_as_set(specs_as_set) { } - std::vector adjacency_list(const SpecAndRemovePlanType& p) const override + std::vector adjacency_list(const RemovePlanAction& p) const override { if (p.plan_type == RemovePlanType::NOT_INSTALLED) { @@ -183,29 +182,20 @@ namespace vcpkg::Dependencies return dependents; } - SpecAndRemovePlanType load_vertex_data(const PackageSpec& spec) const override + RemovePlanAction load_vertex_data(const PackageSpec& spec) const override { + const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end() ? RequestType::USER_REQUESTED : RequestType::AUTO_SELECTED; const StatusParagraphs::const_iterator it = status_db.find_installed(spec); if (it == status_db.end()) { - return { spec, RemovePlanType::NOT_INSTALLED }; + return RemovePlanAction{ spec, RemovePlanType::NOT_INSTALLED, request_type }; } - return { spec, RemovePlanType::REMOVE }; + return RemovePlanAction{ spec, RemovePlanType::REMOVE, request_type }; } }; const std::vector& installed_ports = get_installed_ports(status_db); - const std::vector toposort = Graphs::topological_sort(specs, RemoveAdjacencyProvider{ status_db, installed_ports }); - const std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); - std::vector ret; - for (const SpecAndRemovePlanType& pkg : toposort) - { - auto spec = pkg.spec; - const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end() ? RequestType::USER_REQUESTED : RequestType::AUTO_SELECTED; - RemovePlanAction r(pkg.plan_type, request_type); - ret.push_back(PackageSpecWithRemovePlan(spec, std::move(r))); - } - return ret; + return Graphs::topological_sort(specs, RemoveAdjacencyProvider{ status_db, installed_ports, specs_as_set }); } } -- cgit v1.2.3 From e78827e8cc5c0c75efd8c2c687fc007a922b69a3 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 12 Apr 2017 21:41:54 -0700 Subject: Remove AUTO_SELECTED && ALREADY_INSTALLED packages from the install plan --- toolsrc/src/vcpkg_Dependencies.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index 9952a3f92..9ecf57023 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -142,7 +142,13 @@ namespace vcpkg::Dependencies }; const std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); - return Graphs::topological_sort(specs, InstallAdjacencyProvider{ paths, status_db, specs_as_set }); + std::vector toposort = Graphs::topological_sort(specs, InstallAdjacencyProvider{ paths, status_db, specs_as_set }); + toposort.erase(std::remove_if(toposort.begin(), toposort.end(), [](const InstallPlanAction& p) + { + return p.request_type == RequestType::AUTO_SELECTED && p.plan_type == InstallPlanType::ALREADY_INSTALLED; + }), toposort.end()); + + return toposort; } std::vector create_remove_plan(const std::vector& specs, const StatusParagraphs& status_db) -- cgit v1.2.3 From 8972bd3067f363c055e29ad66254b04513d1df65 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 12 Apr 2017 22:12:37 -0700 Subject: Introduce keep_if function --- toolsrc/include/vcpkg_Util.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/toolsrc/include/vcpkg_Util.h b/toolsrc/include/vcpkg_Util.h index 4ebb2a802..fedf93c7a 100644 --- a/toolsrc/include/vcpkg_Util.h +++ b/toolsrc/include/vcpkg_Util.h @@ -21,4 +21,10 @@ namespace vcpkg::Util return ret; } + + template + void keep_if(Container& cont, Pred pred) + { + cont.erase(std::remove_if(cont.begin(), cont.end(), pred), cont.end()); + } } \ No newline at end of file -- cgit v1.2.3 From b578320d9c3f282ecc8d0ee0d8564a321a31796d Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 12 Apr 2017 22:36:44 -0700 Subject: Add PackageSpec != operator --- toolsrc/include/PackageSpec.h | 1 + toolsrc/src/PackageSpec.cpp | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/toolsrc/include/PackageSpec.h b/toolsrc/include/PackageSpec.h index 4c3b47365..0d69ac89c 100644 --- a/toolsrc/include/PackageSpec.h +++ b/toolsrc/include/PackageSpec.h @@ -25,6 +25,7 @@ namespace vcpkg }; bool operator==(const PackageSpec& left, const PackageSpec& right); + bool operator!=(const PackageSpec& left, const PackageSpec& right); } //namespace vcpkg namespace std diff --git a/toolsrc/src/PackageSpec.cpp b/toolsrc/src/PackageSpec.cpp index bf1c7380c..2a7f4506c 100644 --- a/toolsrc/src/PackageSpec.cpp +++ b/toolsrc/src/PackageSpec.cpp @@ -64,4 +64,9 @@ namespace vcpkg { return left.name() == right.name() && left.triplet() == right.triplet(); } + + bool operator!=(const PackageSpec& left, const PackageSpec& right) + { + return !(left == right); + } } -- cgit v1.2.3 From 3739e8e0b998b14c0f320c21618057e50698c51d Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 12 Apr 2017 22:39:14 -0700 Subject: Use Util::keep_if() --- toolsrc/src/commands_build.cpp | 11 +++++------ toolsrc/src/commands_hash.cpp | 3 ++- toolsrc/src/commands_integrate.cpp | 9 +++++---- toolsrc/src/vcpkg_Dependencies.cpp | 8 ++++---- toolsrc/src/vcpkg_Strings.cpp | 9 +++++---- toolsrc/src/vcpkglib.cpp | 11 +++++------ 6 files changed, 26 insertions(+), 25 deletions(-) diff --git a/toolsrc/src/commands_build.cpp b/toolsrc/src/commands_build.cpp index c3ebd7de8..c7db764de 100644 --- a/toolsrc/src/commands_build.cpp +++ b/toolsrc/src/commands_build.cpp @@ -10,6 +10,7 @@ #include "metrics.h" #include "vcpkg_Enums.h" #include "Paragraphs.h" +#include "vcpkg_Util.h" namespace vcpkg::Commands::Build { @@ -149,12 +150,10 @@ namespace vcpkg::Commands::Build if (result == BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES) { std::vector unmet_dependencies = Dependencies::create_install_plan(paths, { spec }, status_db); - unmet_dependencies.erase( - std::remove_if(unmet_dependencies.begin(), unmet_dependencies.end(), [&spec](const InstallPlanAction& p) - { - return (p.spec == spec) || (p.plan_type == InstallPlanType::ALREADY_INSTALLED); - }), - unmet_dependencies.end()); + Util::keep_if(unmet_dependencies, [&spec](const InstallPlanAction& p) + { + return (p.spec != spec) && (p.plan_type != InstallPlanType::ALREADY_INSTALLED); + }); Checks::check_exit(VCPKG_LINE_INFO, !unmet_dependencies.empty()); System::println(System::Color::error, "The build command requires all dependencies to be already installed."); diff --git a/toolsrc/src/commands_hash.cpp b/toolsrc/src/commands_hash.cpp index 2ffa3a9aa..a9024d9e7 100644 --- a/toolsrc/src/commands_hash.cpp +++ b/toolsrc/src/commands_hash.cpp @@ -1,6 +1,7 @@ #include "pch.h" #include "vcpkg_Commands.h" #include "vcpkg_System.h" +#include "vcpkg_Util.h" namespace vcpkg::Commands::Hash { @@ -20,7 +21,7 @@ namespace vcpkg::Commands::Hash Checks::check_exit(VCPKG_LINE_INFO, end != std::string::npos, "Unexpected output format from command: %s", Strings::utf16_to_utf8(cmd_line)); auto hash = output.substr(start, end - start); - hash.erase(std::remove_if(hash.begin(), hash.end(), isspace), hash.end()); + Util::keep_if(hash, [](char c) {return !isspace(c); }); System::println(hash); } diff --git a/toolsrc/src/commands_integrate.cpp b/toolsrc/src/commands_integrate.cpp index 256c3ad1d..e51b1637e 100644 --- a/toolsrc/src/commands_integrate.cpp +++ b/toolsrc/src/commands_integrate.cpp @@ -3,6 +3,7 @@ #include "vcpkg_Checks.h" #include "vcpkg_System.h" #include "vcpkg_Files.h" +#include "vcpkg_Util.h" namespace vcpkg::Commands::Integrate { @@ -66,10 +67,10 @@ namespace vcpkg::Commands::Integrate dir_id.erase(1, 1); // Erasing the ":" // NuGet id cannot have invalid characters. We will only use alphanumeric and dot. - dir_id.erase(std::remove_if(dir_id.begin(), dir_id.end(), [](char c) - { - return !isalnum(c) && (c != '.'); - }), dir_id.end()); + Util::keep_if(dir_id, [](char c) + { + return isalnum(c) || (c == '.'); + }); const std::string nuget_id = "vcpkg." + dir_id; return nuget_id; diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp index 9ecf57023..5e2a1214c 100644 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ b/toolsrc/src/vcpkg_Dependencies.cpp @@ -143,10 +143,10 @@ namespace vcpkg::Dependencies const std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); std::vector toposort = Graphs::topological_sort(specs, InstallAdjacencyProvider{ paths, status_db, specs_as_set }); - toposort.erase(std::remove_if(toposort.begin(), toposort.end(), [](const InstallPlanAction& p) - { - return p.request_type == RequestType::AUTO_SELECTED && p.plan_type == InstallPlanType::ALREADY_INSTALLED; - }), toposort.end()); + Util::keep_if(toposort, [](const InstallPlanAction& p) + { + return !(p.request_type == RequestType::AUTO_SELECTED && p.plan_type == InstallPlanType::ALREADY_INSTALLED); + }); return toposort; } diff --git a/toolsrc/src/vcpkg_Strings.cpp b/toolsrc/src/vcpkg_Strings.cpp index 26dc6388b..3d9895436 100644 --- a/toolsrc/src/vcpkg_Strings.cpp +++ b/toolsrc/src/vcpkg_Strings.cpp @@ -1,5 +1,6 @@ #include "pch.h" #include "vcpkg_Strings.h" +#include "vcpkg_Util.h" namespace vcpkg::Strings::details { @@ -98,10 +99,10 @@ namespace vcpkg::Strings trim(&s); } - strings->erase(std::remove_if(strings->begin(), strings->end(), [](const std::string& s)-> bool - { - return s == ""; - }), strings->end()); + Util::keep_if(*strings, [](const std::string& s)-> bool + { + return s != ""; + }); } std::vector split(const std::string& s, const std::string& delimiter) diff --git a/toolsrc/src/vcpkglib.cpp b/toolsrc/src/vcpkglib.cpp index 5e847019f..fb1f39256 100644 --- a/toolsrc/src/vcpkglib.cpp +++ b/toolsrc/src/vcpkglib.cpp @@ -4,6 +4,7 @@ #include "Paragraphs.h" #include "metrics.h" #include "vcpkg_Strings.h" +#include "vcpkg_Util.h" namespace vcpkg { @@ -201,12 +202,10 @@ namespace vcpkg upgrade_to_slash_terminated_sorted_format(&installed_files_of_current_pgh, listfile_path); // Remove the directories - installed_files_of_current_pgh.erase( - std::remove_if(installed_files_of_current_pgh.begin(), installed_files_of_current_pgh.end(), [](const std::string& file) -> bool - { - return file.back() == '/'; - } - ), installed_files_of_current_pgh.end()); + Util::keep_if(installed_files_of_current_pgh, [](const std::string& file) -> bool + { + return file.back() != '/'; + }); StatusParagraphAndAssociatedFiles pgh_and_files = { *pgh, SortedVector(std::move(installed_files_of_current_pgh)) }; installed_files.push_back(std::move(pgh_and_files)); -- cgit v1.2.3