mirror of
https://github.com/microsoft/vcpkg.git
synced 2024-11-25 10:09:06 +08:00
Add skeleton code for vcpkg export
This commit is contained in:
parent
47322f74bd
commit
92cf32d59a
@ -65,6 +65,11 @@ namespace vcpkg::Commands
|
||||
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet);
|
||||
}
|
||||
|
||||
namespace Export
|
||||
{
|
||||
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet);
|
||||
}
|
||||
|
||||
namespace CI
|
||||
{
|
||||
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet);
|
||||
|
@ -73,7 +73,33 @@ namespace vcpkg::Dependencies
|
||||
RequestType request_type;
|
||||
};
|
||||
|
||||
enum class ExportPlanType
|
||||
{
|
||||
UNKNOWN,
|
||||
PORT_AVAILABLE_BUT_NOT_BUILT,
|
||||
ALREADY_BUILT
|
||||
};
|
||||
|
||||
struct ExportPlanAction
|
||||
{
|
||||
static bool compare_by_name(const ExportPlanAction* left, const ExportPlanAction* right);
|
||||
|
||||
ExportPlanAction();
|
||||
ExportPlanAction(const PackageSpec& spec, const AnyParagraph& any_paragraph, const RequestType& request_type);
|
||||
ExportPlanAction(const ExportPlanAction&) = delete;
|
||||
ExportPlanAction(ExportPlanAction&&) = default;
|
||||
ExportPlanAction& operator=(const ExportPlanAction&) = delete;
|
||||
ExportPlanAction& operator=(ExportPlanAction&&) = default;
|
||||
|
||||
PackageSpec spec;
|
||||
AnyParagraph any_paragraph;
|
||||
ExportPlanType plan_type;
|
||||
RequestType request_type;
|
||||
};
|
||||
|
||||
std::vector<InstallPlanAction> create_install_plan(const VcpkgPaths& paths, const std::vector<PackageSpec>& specs, const StatusParagraphs& status_db);
|
||||
|
||||
std::vector<RemovePlanAction> create_remove_plan(const std::vector<PackageSpec>& specs, const StatusParagraphs& status_db);
|
||||
|
||||
std::vector<ExportPlanAction> create_export_plan(const VcpkgPaths& paths, const std::vector<PackageSpec>& specs, const StatusParagraphs& status_db);
|
||||
}
|
||||
|
@ -11,7 +11,8 @@ namespace vcpkg::Commands
|
||||
{ "remove", &Remove::perform_and_exit },
|
||||
{ "build", &Build::perform_and_exit },
|
||||
{ "env", &Env::perform_and_exit },
|
||||
{ "build-external", &BuildExternal::perform_and_exit }
|
||||
{ "build-external", &BuildExternal::perform_and_exit },
|
||||
{ "export", &Export::perform_and_exit },
|
||||
};
|
||||
return t;
|
||||
}
|
||||
@ -31,7 +32,7 @@ namespace vcpkg::Commands
|
||||
{ "create", &Create::perform_and_exit },
|
||||
{ "import", &Import::perform_and_exit },
|
||||
{ "cache", &Cache::perform_and_exit },
|
||||
{ "portsdiff", &PortsDiff::perform_and_exit }
|
||||
{ "portsdiff", &PortsDiff::perform_and_exit },
|
||||
};
|
||||
return t;
|
||||
}
|
||||
|
93
toolsrc/src/commands_export.cpp
Normal file
93
toolsrc/src/commands_export.cpp
Normal file
@ -0,0 +1,93 @@
|
||||
#include "pch.h"
|
||||
#include "vcpkg_Commands.h"
|
||||
#include "vcpkglib.h"
|
||||
#include "vcpkg_System.h"
|
||||
#include "vcpkg_Dependencies.h"
|
||||
#include "vcpkg_Input.h"
|
||||
#include "vcpkg_Util.h"
|
||||
#include "Paragraphs.h"
|
||||
|
||||
namespace vcpkg::Commands::Export
|
||||
{
|
||||
using Dependencies::ExportPlanAction;
|
||||
using Dependencies::RequestType;
|
||||
using Dependencies::ExportPlanType;
|
||||
|
||||
static void print_plan(const std::vector<ExportPlanAction>& plan)
|
||||
{
|
||||
static constexpr std::array<ExportPlanType, 2> order = { ExportPlanType::ALREADY_BUILT, ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT };
|
||||
|
||||
std::map<ExportPlanType, std::vector<const ExportPlanAction*>> group_by_plan_type;
|
||||
Util::group_by(plan, &group_by_plan_type, [](const ExportPlanAction& p) { return p.plan_type; });
|
||||
|
||||
for (const ExportPlanType plan_type : order)
|
||||
{
|
||||
auto it = group_by_plan_type.find(plan_type);
|
||||
if (it == group_by_plan_type.cend())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
std::vector<const ExportPlanAction*> cont = it->second;
|
||||
std::sort(cont.begin(), cont.end(), &ExportPlanAction::compare_by_name);
|
||||
const std::string as_string = Strings::join("\n", cont, [](const ExportPlanAction* p)
|
||||
{
|
||||
return Dependencies::to_output_string(p->request_type, p->spec.to_string());
|
||||
});
|
||||
|
||||
switch (plan_type)
|
||||
{
|
||||
case ExportPlanType::ALREADY_BUILT:
|
||||
System::println("The following packages are already built and will be exported:\n%s", as_string);
|
||||
continue;
|
||||
case ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT:
|
||||
System::println("The following packages need to be built:\n%s", as_string);
|
||||
continue;
|
||||
default:
|
||||
Checks::unreachable(VCPKG_LINE_INFO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet)
|
||||
{
|
||||
static const std::string OPTION_DRY_RUN = "--dry-run";
|
||||
// input sanitization
|
||||
static const std::string example = Commands::Help::create_example_string("export zlib zlib:x64-windows curl boost");
|
||||
args.check_min_arg_count(1, example);
|
||||
|
||||
const std::vector<PackageSpec> specs = Util::fmap(args.command_arguments, [&](auto&& arg)
|
||||
{
|
||||
return Input::check_and_get_package_spec(arg, default_triplet, example);
|
||||
});
|
||||
for (auto&& spec : specs)
|
||||
Input::check_triplet(spec.triplet(), paths);
|
||||
|
||||
const std::unordered_set<std::string> options = args.check_and_get_optional_command_arguments({ OPTION_DRY_RUN });
|
||||
const bool dryRun = options.find(OPTION_DRY_RUN) != options.cend();
|
||||
|
||||
// create the plan
|
||||
StatusParagraphs status_db = database_load_check(paths);
|
||||
std::vector<ExportPlanAction> export_plan = Dependencies::create_export_plan(paths, specs, status_db);
|
||||
Checks::check_exit(VCPKG_LINE_INFO, !export_plan.empty(), "Export plan cannot be empty");
|
||||
|
||||
print_plan(export_plan);
|
||||
|
||||
const bool has_non_user_requested_packages = std::find_if(export_plan.cbegin(), export_plan.cend(), [](const ExportPlanAction& package)-> bool
|
||||
{
|
||||
return package.request_type != RequestType::USER_REQUESTED;
|
||||
}) != export_plan.cend();
|
||||
|
||||
if (has_non_user_requested_packages)
|
||||
{
|
||||
System::println(System::Color::warning, "Additional packages (*) need to be exported to complete this operation.");
|
||||
}
|
||||
|
||||
if (dryRun)
|
||||
{
|
||||
Checks::exit_success(VCPKG_LINE_INFO);
|
||||
}
|
||||
|
||||
Checks::exit_success(VCPKG_LINE_INFO);
|
||||
}
|
||||
}
|
@ -98,6 +98,38 @@ namespace vcpkg::Dependencies
|
||||
, plan_type(plan_type)
|
||||
, request_type(request_type) { }
|
||||
|
||||
bool ExportPlanAction::compare_by_name(const ExportPlanAction* left, const ExportPlanAction* right)
|
||||
{
|
||||
return left->spec.name() < right->spec.name();
|
||||
}
|
||||
|
||||
ExportPlanAction::ExportPlanAction() : spec()
|
||||
, any_paragraph()
|
||||
, plan_type(ExportPlanType::UNKNOWN)
|
||||
, request_type(RequestType::UNKNOWN) { }
|
||||
|
||||
ExportPlanAction::ExportPlanAction(const PackageSpec& spec, const AnyParagraph& any_paragraph, const RequestType& request_type) : ExportPlanAction()
|
||||
{
|
||||
this->spec = spec;
|
||||
this->request_type = request_type;
|
||||
|
||||
if (auto p = any_paragraph.binary_paragraph.get())
|
||||
{
|
||||
this->plan_type = ExportPlanType::ALREADY_BUILT;
|
||||
this->any_paragraph.binary_paragraph = *p;
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto p = any_paragraph.source_paragraph.get())
|
||||
{
|
||||
this->plan_type = ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT;
|
||||
this->any_paragraph.source_paragraph = *p;
|
||||
return;
|
||||
}
|
||||
|
||||
this->plan_type = ExportPlanType::UNKNOWN;
|
||||
}
|
||||
|
||||
bool RemovePlanAction::compare_by_name(const RemovePlanAction* left, const RemovePlanAction* right)
|
||||
{
|
||||
return left->spec.name() < right->spec.name();
|
||||
@ -204,4 +236,42 @@ namespace vcpkg::Dependencies
|
||||
const std::unordered_set<PackageSpec> specs_as_set(specs.cbegin(), specs.cend());
|
||||
return Graphs::topological_sort(specs, RemoveAdjacencyProvider{ status_db, installed_ports, specs_as_set });
|
||||
}
|
||||
|
||||
std::vector<ExportPlanAction> create_export_plan(const VcpkgPaths& paths, const std::vector<PackageSpec>& specs, const StatusParagraphs& status_db)
|
||||
{
|
||||
struct ExportAdjacencyProvider final : Graphs::AdjacencyProvider<PackageSpec, ExportPlanAction>
|
||||
{
|
||||
const VcpkgPaths& paths;
|
||||
const StatusParagraphs& status_db;
|
||||
const std::unordered_set<PackageSpec>& specs_as_set;
|
||||
|
||||
ExportAdjacencyProvider(const VcpkgPaths& p, const StatusParagraphs& s, const std::unordered_set<PackageSpec>& specs_as_set) : paths(p)
|
||||
, status_db(s)
|
||||
, specs_as_set(specs_as_set) {}
|
||||
|
||||
std::vector<PackageSpec> adjacency_list(const ExportPlanAction& plan) const override
|
||||
{
|
||||
return plan.any_paragraph.dependencies(plan.spec.triplet());
|
||||
}
|
||||
|
||||
ExportPlanAction 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;
|
||||
|
||||
Expected<BinaryParagraph> maybe_bpgh = Paragraphs::try_load_cached_package(paths, spec);
|
||||
if (auto bpgh = maybe_bpgh.get())
|
||||
return ExportPlanAction{ spec,{ nullopt, *bpgh, nullopt }, request_type };
|
||||
|
||||
Expected<SourceParagraph> maybe_spgh = Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(spec));
|
||||
if (auto spgh = maybe_spgh.get())
|
||||
return ExportPlanAction{ spec,{ nullopt, nullopt, *spgh }, request_type };
|
||||
|
||||
return ExportPlanAction{ spec ,{ nullopt, nullopt, nullopt }, request_type };
|
||||
}
|
||||
};
|
||||
|
||||
const std::unordered_set<PackageSpec> specs_as_set(specs.cbegin(), specs.cend());
|
||||
std::vector<ExportPlanAction> toposort = Graphs::topological_sort(specs, ExportAdjacencyProvider{ paths, status_db, specs_as_set });
|
||||
return toposort;
|
||||
}
|
||||
}
|
||||
|
@ -187,6 +187,7 @@
|
||||
<ClCompile Include="..\src\commands_ci.cpp" />
|
||||
<ClCompile Include="..\src\commands_depends.cpp" />
|
||||
<ClCompile Include="..\src\commands_env.cpp" />
|
||||
<ClCompile Include="..\src\commands_export.cpp" />
|
||||
<ClCompile Include="..\src\LineInfo.cpp" />
|
||||
<ClCompile Include="..\src\ParagraphParseResult.cpp" />
|
||||
<ClCompile Include="..\src\PostBuildLint_BuildInfo.cpp" />
|
||||
|
@ -183,6 +183,9 @@
|
||||
<ClCompile Include="..\src\commands_depends.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\commands_export.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\include\SourceParagraph.h">
|
||||
|
Loading…
Reference in New Issue
Block a user