mirror of
https://github.com/microsoft/vcpkg.git
synced 2025-01-14 06:28:00 +08:00
[vcpkg formatting] Turn off DeriveLineEnding (#12368)
* [vcpkg formatting] Turn off DeriveLineEnding * format * Add newlines to the end of files Since we're reformatting anyways
This commit is contained in:
parent
e554608135
commit
d2620cf02b
@ -31,6 +31,7 @@ ForEachMacros: [TEST_CASE, SECTION]
|
||||
PenaltyReturnTypeOnItsOwnLine: 1000
|
||||
SpaceAfterTemplateKeyword: false
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
DeriveLineEnding: false
|
||||
UseCRLF: false
|
||||
|
||||
IncludeBlocks: Regroup
|
||||
|
@ -1,38 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include <vcpkg/cmakevars.h>
|
||||
|
||||
namespace vcpkg::Test
|
||||
{
|
||||
struct MockCMakeVarProvider : CMakeVars::CMakeVarProvider
|
||||
{
|
||||
void load_generic_triplet_vars(Triplet triplet) const override { generic_triplet_vars[triplet] = {}; }
|
||||
|
||||
void load_dep_info_vars(Span<const PackageSpec> specs) const override
|
||||
{
|
||||
for (auto&& spec : specs)
|
||||
dep_info_vars[spec] = {};
|
||||
}
|
||||
|
||||
void load_tag_vars(Span<const FullPackageSpec> specs,
|
||||
const PortFileProvider::PortFileProvider& port_provider) const override
|
||||
{
|
||||
for (auto&& spec : specs)
|
||||
tag_vars[spec.package_spec] = {};
|
||||
Util::unused(port_provider);
|
||||
}
|
||||
|
||||
Optional<const std::unordered_map<std::string, std::string>&> get_generic_triplet_vars(
|
||||
Triplet triplet) const override;
|
||||
|
||||
Optional<const std::unordered_map<std::string, std::string>&> get_dep_info_vars(
|
||||
const PackageSpec& spec) const override;
|
||||
|
||||
Optional<const std::unordered_map<std::string, std::string>&> get_tag_vars(
|
||||
const PackageSpec& spec) const override;
|
||||
|
||||
mutable std::unordered_map<PackageSpec, std::unordered_map<std::string, std::string>> dep_info_vars;
|
||||
mutable std::unordered_map<PackageSpec, std::unordered_map<std::string, std::string>> tag_vars;
|
||||
mutable std::unordered_map<Triplet, std::unordered_map<std::string, std::string>> generic_triplet_vars;
|
||||
};
|
||||
}
|
||||
#pragma once
|
||||
|
||||
#include <vcpkg/cmakevars.h>
|
||||
|
||||
namespace vcpkg::Test
|
||||
{
|
||||
struct MockCMakeVarProvider : CMakeVars::CMakeVarProvider
|
||||
{
|
||||
void load_generic_triplet_vars(Triplet triplet) const override { generic_triplet_vars[triplet] = {}; }
|
||||
|
||||
void load_dep_info_vars(Span<const PackageSpec> specs) const override
|
||||
{
|
||||
for (auto&& spec : specs)
|
||||
dep_info_vars[spec] = {};
|
||||
}
|
||||
|
||||
void load_tag_vars(Span<const FullPackageSpec> specs,
|
||||
const PortFileProvider::PortFileProvider& port_provider) const override
|
||||
{
|
||||
for (auto&& spec : specs)
|
||||
tag_vars[spec.package_spec] = {};
|
||||
Util::unused(port_provider);
|
||||
}
|
||||
|
||||
Optional<const std::unordered_map<std::string, std::string>&> get_generic_triplet_vars(
|
||||
Triplet triplet) const override;
|
||||
|
||||
Optional<const std::unordered_map<std::string, std::string>&> get_dep_info_vars(
|
||||
const PackageSpec& spec) const override;
|
||||
|
||||
Optional<const std::unordered_map<std::string, std::string>&> get_tag_vars(
|
||||
const PackageSpec& spec) const override;
|
||||
|
||||
mutable std::unordered_map<PackageSpec, std::unordered_map<std::string, std::string>> dep_info_vars;
|
||||
mutable std::unordered_map<PackageSpec, std::unordered_map<std::string, std::string>> tag_vars;
|
||||
mutable std::unordered_map<Triplet, std::unordered_map<std::string, std::string>> generic_triplet_vars;
|
||||
};
|
||||
}
|
||||
|
@ -1,21 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace vcpkg
|
||||
{
|
||||
template<class Key, class Value>
|
||||
struct Cache
|
||||
{
|
||||
template<class F>
|
||||
Value const& get_lazy(const Key& k, const F& f) const
|
||||
{
|
||||
auto it = m_cache.find(k);
|
||||
if (it != m_cache.end()) return it->second;
|
||||
return m_cache.emplace(k, f()).first->second;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable std::map<Key, Value> m_cache;
|
||||
};
|
||||
}
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace vcpkg
|
||||
{
|
||||
template<class Key, class Value>
|
||||
struct Cache
|
||||
{
|
||||
template<class F>
|
||||
Value const& get_lazy(const Key& k, const F& f) const
|
||||
{
|
||||
auto it = m_cache.find(k);
|
||||
if (it != m_cache.end()) return it->second;
|
||||
return m_cache.emplace(k, f()).first->second;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable std::map<Key, Value> m_cache;
|
||||
};
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
namespace vcpkg
|
||||
{
|
||||
struct ignore_errors_t
|
||||
{
|
||||
};
|
||||
|
||||
constexpr ignore_errors_t ignore_errors;
|
||||
}
|
||||
#pragma once
|
||||
|
||||
namespace vcpkg
|
||||
{
|
||||
struct ignore_errors_t
|
||||
{
|
||||
};
|
||||
|
||||
constexpr ignore_errors_t ignore_errors;
|
||||
}
|
||||
|
@ -1,57 +1,57 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <initializer_list>
|
||||
#include <vector>
|
||||
|
||||
namespace vcpkg
|
||||
{
|
||||
template<class T>
|
||||
struct Span
|
||||
{
|
||||
public:
|
||||
static_assert(std::is_object<T>::value, "Span<non-object-type> is illegal");
|
||||
|
||||
using value_type = std::decay_t<T>;
|
||||
using element_type = T;
|
||||
using pointer = std::add_pointer_t<T>;
|
||||
using reference = std::add_lvalue_reference_t<T>;
|
||||
using iterator = pointer;
|
||||
|
||||
constexpr Span() noexcept : m_ptr(nullptr), m_count(0) { }
|
||||
constexpr Span(std::nullptr_t) noexcept : m_ptr(nullptr), m_count(0) { }
|
||||
constexpr Span(pointer ptr, size_t count) noexcept : m_ptr(ptr), m_count(count) { }
|
||||
constexpr Span(pointer ptr_begin, pointer ptr_end) noexcept : m_ptr(ptr_begin), m_count(ptr_end - ptr_begin) { }
|
||||
|
||||
template<size_t N>
|
||||
constexpr Span(T (&arr)[N]) noexcept : m_ptr(arr), m_count(N)
|
||||
{
|
||||
}
|
||||
|
||||
template<size_t N, class = std::enable_if_t<std::is_const_v<T>>>
|
||||
constexpr Span(std::remove_const_t<T> (&arr)[N]) noexcept : m_ptr(arr), m_count(N)
|
||||
{
|
||||
}
|
||||
|
||||
template<class Range,
|
||||
class = decltype(std::declval<Range>().data()),
|
||||
class = std::enable_if_t<!std::is_same<std::decay_t<Range>, Span>::value>>
|
||||
constexpr Span(Range&& v) noexcept : Span(v.data(), v.size())
|
||||
{
|
||||
static_assert(std::is_same<typename std::decay_t<Range>::value_type, value_type>::value,
|
||||
"Cannot convert incompatible ranges");
|
||||
}
|
||||
|
||||
constexpr iterator begin() const { return m_ptr; }
|
||||
constexpr iterator end() const { return m_ptr + m_count; }
|
||||
|
||||
constexpr reference operator[](size_t i) const { return m_ptr[i]; }
|
||||
constexpr pointer data() const { return m_ptr; }
|
||||
constexpr size_t size() const { return m_count; }
|
||||
|
||||
private:
|
||||
pointer m_ptr;
|
||||
size_t m_count;
|
||||
};
|
||||
}
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <initializer_list>
|
||||
#include <vector>
|
||||
|
||||
namespace vcpkg
|
||||
{
|
||||
template<class T>
|
||||
struct Span
|
||||
{
|
||||
public:
|
||||
static_assert(std::is_object<T>::value, "Span<non-object-type> is illegal");
|
||||
|
||||
using value_type = std::decay_t<T>;
|
||||
using element_type = T;
|
||||
using pointer = std::add_pointer_t<T>;
|
||||
using reference = std::add_lvalue_reference_t<T>;
|
||||
using iterator = pointer;
|
||||
|
||||
constexpr Span() noexcept : m_ptr(nullptr), m_count(0) { }
|
||||
constexpr Span(std::nullptr_t) noexcept : m_ptr(nullptr), m_count(0) { }
|
||||
constexpr Span(pointer ptr, size_t count) noexcept : m_ptr(ptr), m_count(count) { }
|
||||
constexpr Span(pointer ptr_begin, pointer ptr_end) noexcept : m_ptr(ptr_begin), m_count(ptr_end - ptr_begin) { }
|
||||
|
||||
template<size_t N>
|
||||
constexpr Span(T (&arr)[N]) noexcept : m_ptr(arr), m_count(N)
|
||||
{
|
||||
}
|
||||
|
||||
template<size_t N, class = std::enable_if_t<std::is_const_v<T>>>
|
||||
constexpr Span(std::remove_const_t<T> (&arr)[N]) noexcept : m_ptr(arr), m_count(N)
|
||||
{
|
||||
}
|
||||
|
||||
template<class Range,
|
||||
class = decltype(std::declval<Range>().data()),
|
||||
class = std::enable_if_t<!std::is_same<std::decay_t<Range>, Span>::value>>
|
||||
constexpr Span(Range&& v) noexcept : Span(v.data(), v.size())
|
||||
{
|
||||
static_assert(std::is_same<typename std::decay_t<Range>::value_type, value_type>::value,
|
||||
"Cannot convert incompatible ranges");
|
||||
}
|
||||
|
||||
constexpr iterator begin() const { return m_ptr; }
|
||||
constexpr iterator end() const { return m_ptr + m_count; }
|
||||
|
||||
constexpr reference operator[](size_t i) const { return m_ptr[i]; }
|
||||
constexpr pointer data() const { return m_ptr; }
|
||||
constexpr size_t size() const { return m_count; }
|
||||
|
||||
private:
|
||||
pointer m_ptr;
|
||||
size_t m_count;
|
||||
};
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <vcpkg/base/span.h>
|
||||
|
||||
namespace vcpkg
|
||||
{
|
||||
template<class T>
|
||||
using View = Span<const T>;
|
||||
}
|
||||
#pragma once
|
||||
|
||||
#include <vcpkg/base/span.h>
|
||||
|
||||
namespace vcpkg
|
||||
{
|
||||
template<class T>
|
||||
using View = Span<const T>;
|
||||
}
|
||||
|
@ -1,53 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#include <vcpkg/base/expected.h>
|
||||
#include <vcpkg/base/files.h>
|
||||
|
||||
#include <vcpkg/packagespec.h>
|
||||
#include <vcpkg/vcpkgpaths.h>
|
||||
|
||||
namespace vcpkg::Dependencies
|
||||
{
|
||||
struct InstallPlanAction;
|
||||
struct ActionPlan;
|
||||
}
|
||||
namespace vcpkg::Build
|
||||
{
|
||||
struct AbiTagAndFile;
|
||||
struct BuildPackageOptions;
|
||||
}
|
||||
|
||||
namespace vcpkg
|
||||
{
|
||||
enum class RestoreResult
|
||||
{
|
||||
missing,
|
||||
success,
|
||||
build_failed,
|
||||
};
|
||||
|
||||
struct IBinaryProvider
|
||||
{
|
||||
virtual ~IBinaryProvider() = default;
|
||||
/// Gives the BinaryProvider an opportunity to batch any downloading or server communication for executing
|
||||
/// `plan`.
|
||||
virtual void prefetch(const VcpkgPaths& paths, const Dependencies::ActionPlan& plan) = 0;
|
||||
/// Attempts to restore the package referenced by `action` into the packages directory.
|
||||
virtual RestoreResult try_restore(const VcpkgPaths& paths, const Dependencies::InstallPlanAction& action) = 0;
|
||||
/// Called upon a successful build of `action`
|
||||
virtual void push_success(const VcpkgPaths& paths, const Dependencies::InstallPlanAction& action) = 0;
|
||||
/// Requests the result of `try_restore()` without actually downloading the package. Used by CI to determine
|
||||
/// missing packages.
|
||||
virtual RestoreResult precheck(const VcpkgPaths& paths, const Dependencies::InstallPlanAction& action) = 0;
|
||||
};
|
||||
|
||||
IBinaryProvider& null_binary_provider();
|
||||
|
||||
ExpectedS<std::unique_ptr<IBinaryProvider>> create_binary_provider_from_configs(View<std::string> args);
|
||||
ExpectedS<std::unique_ptr<IBinaryProvider>> create_binary_provider_from_configs_pure(const std::string& env_string,
|
||||
View<std::string> args);
|
||||
|
||||
std::string generate_nuget_packages_config(const Dependencies::ActionPlan& action);
|
||||
|
||||
void help_topic_binary_caching(const VcpkgPaths& paths);
|
||||
}
|
||||
#pragma once
|
||||
|
||||
#include <vcpkg/base/expected.h>
|
||||
#include <vcpkg/base/files.h>
|
||||
|
||||
#include <vcpkg/packagespec.h>
|
||||
#include <vcpkg/vcpkgpaths.h>
|
||||
|
||||
namespace vcpkg::Dependencies
|
||||
{
|
||||
struct InstallPlanAction;
|
||||
struct ActionPlan;
|
||||
}
|
||||
namespace vcpkg::Build
|
||||
{
|
||||
struct AbiTagAndFile;
|
||||
struct BuildPackageOptions;
|
||||
}
|
||||
|
||||
namespace vcpkg
|
||||
{
|
||||
enum class RestoreResult
|
||||
{
|
||||
missing,
|
||||
success,
|
||||
build_failed,
|
||||
};
|
||||
|
||||
struct IBinaryProvider
|
||||
{
|
||||
virtual ~IBinaryProvider() = default;
|
||||
/// Gives the BinaryProvider an opportunity to batch any downloading or server communication for executing
|
||||
/// `plan`.
|
||||
virtual void prefetch(const VcpkgPaths& paths, const Dependencies::ActionPlan& plan) = 0;
|
||||
/// Attempts to restore the package referenced by `action` into the packages directory.
|
||||
virtual RestoreResult try_restore(const VcpkgPaths& paths, const Dependencies::InstallPlanAction& action) = 0;
|
||||
/// Called upon a successful build of `action`
|
||||
virtual void push_success(const VcpkgPaths& paths, const Dependencies::InstallPlanAction& action) = 0;
|
||||
/// Requests the result of `try_restore()` without actually downloading the package. Used by CI to determine
|
||||
/// missing packages.
|
||||
virtual RestoreResult precheck(const VcpkgPaths& paths, const Dependencies::InstallPlanAction& action) = 0;
|
||||
};
|
||||
|
||||
IBinaryProvider& null_binary_provider();
|
||||
|
||||
ExpectedS<std::unique_ptr<IBinaryProvider>> create_binary_provider_from_configs(View<std::string> args);
|
||||
ExpectedS<std::unique_ptr<IBinaryProvider>> create_binary_provider_from_configs_pure(const std::string& env_string,
|
||||
View<std::string> args);
|
||||
|
||||
std::string generate_nuget_packages_config(const Dependencies::ActionPlan& action);
|
||||
|
||||
void help_topic_binary_caching(const VcpkgPaths& paths);
|
||||
}
|
||||
|
@ -1,60 +1,60 @@
|
||||
#pragma once
|
||||
|
||||
#include <vcpkg/dependencies.h>
|
||||
#include <vcpkg/packagespec.h>
|
||||
#include <vcpkg/vcpkgpaths.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace vcpkg
|
||||
{
|
||||
std::string reformat_version(const std::string& version, const std::string& abi_tag);
|
||||
|
||||
struct NugetReference
|
||||
{
|
||||
explicit NugetReference(const Dependencies::InstallPlanAction& action)
|
||||
: NugetReference(action.spec,
|
||||
action.source_control_file_location.value_or_exit(VCPKG_LINE_INFO)
|
||||
.source_control_file->core_paragraph->version,
|
||||
action.abi_info.value_or_exit(VCPKG_LINE_INFO).package_abi)
|
||||
{
|
||||
}
|
||||
|
||||
NugetReference(const PackageSpec& spec, const std::string& raw_version, const std::string& abi_tag)
|
||||
: id(spec.dir()), version(reformat_version(raw_version, abi_tag))
|
||||
{
|
||||
}
|
||||
|
||||
std::string id;
|
||||
std::string version;
|
||||
|
||||
std::string nupkg_filename() const { return Strings::concat(id, '.', version, ".nupkg"); }
|
||||
};
|
||||
|
||||
std::string generate_nuspec(const VcpkgPaths& paths,
|
||||
const Dependencies::InstallPlanAction& action,
|
||||
const NugetReference& ref);
|
||||
|
||||
struct XmlSerializer
|
||||
{
|
||||
XmlSerializer& emit_declaration();
|
||||
XmlSerializer& open_tag(StringLiteral sl);
|
||||
XmlSerializer& start_complex_open_tag(StringLiteral sl);
|
||||
XmlSerializer& text_attr(StringLiteral name, StringView content);
|
||||
XmlSerializer& finish_complex_open_tag();
|
||||
XmlSerializer& finish_self_closing_complex_tag();
|
||||
XmlSerializer& close_tag(StringLiteral sl);
|
||||
XmlSerializer& text(StringView sv);
|
||||
XmlSerializer& simple_tag(StringLiteral tag, StringView content);
|
||||
XmlSerializer& line_break();
|
||||
|
||||
std::string buf;
|
||||
|
||||
private:
|
||||
XmlSerializer& emit_pending_indent();
|
||||
|
||||
int m_indent = 0;
|
||||
bool m_pending_indent = false;
|
||||
};
|
||||
|
||||
}
|
||||
#pragma once
|
||||
|
||||
#include <vcpkg/dependencies.h>
|
||||
#include <vcpkg/packagespec.h>
|
||||
#include <vcpkg/vcpkgpaths.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace vcpkg
|
||||
{
|
||||
std::string reformat_version(const std::string& version, const std::string& abi_tag);
|
||||
|
||||
struct NugetReference
|
||||
{
|
||||
explicit NugetReference(const Dependencies::InstallPlanAction& action)
|
||||
: NugetReference(action.spec,
|
||||
action.source_control_file_location.value_or_exit(VCPKG_LINE_INFO)
|
||||
.source_control_file->core_paragraph->version,
|
||||
action.abi_info.value_or_exit(VCPKG_LINE_INFO).package_abi)
|
||||
{
|
||||
}
|
||||
|
||||
NugetReference(const PackageSpec& spec, const std::string& raw_version, const std::string& abi_tag)
|
||||
: id(spec.dir()), version(reformat_version(raw_version, abi_tag))
|
||||
{
|
||||
}
|
||||
|
||||
std::string id;
|
||||
std::string version;
|
||||
|
||||
std::string nupkg_filename() const { return Strings::concat(id, '.', version, ".nupkg"); }
|
||||
};
|
||||
|
||||
std::string generate_nuspec(const VcpkgPaths& paths,
|
||||
const Dependencies::InstallPlanAction& action,
|
||||
const NugetReference& ref);
|
||||
|
||||
struct XmlSerializer
|
||||
{
|
||||
XmlSerializer& emit_declaration();
|
||||
XmlSerializer& open_tag(StringLiteral sl);
|
||||
XmlSerializer& start_complex_open_tag(StringLiteral sl);
|
||||
XmlSerializer& text_attr(StringLiteral name, StringView content);
|
||||
XmlSerializer& finish_complex_open_tag();
|
||||
XmlSerializer& finish_self_closing_complex_tag();
|
||||
XmlSerializer& close_tag(StringLiteral sl);
|
||||
XmlSerializer& text(StringView sv);
|
||||
XmlSerializer& simple_tag(StringLiteral tag, StringView content);
|
||||
XmlSerializer& line_break();
|
||||
|
||||
std::string buf;
|
||||
|
||||
private:
|
||||
XmlSerializer& emit_pending_indent();
|
||||
|
||||
int m_indent = 0;
|
||||
bool m_pending_indent = false;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
#include <vcpkg/base/system.process.h>
|
||||
|
||||
#include <vcpkg/vcpkgpaths.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace vcpkg
|
||||
{
|
||||
std::string make_cmake_cmd(const VcpkgPaths& paths,
|
||||
const fs::path& cmake_script,
|
||||
std::vector<System::CMakeVariable>&& pass_variables);
|
||||
}
|
||||
#include <vcpkg/base/system.process.h>
|
||||
|
||||
#include <vcpkg/vcpkgpaths.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace vcpkg
|
||||
{
|
||||
std::string make_cmake_cmd(const VcpkgPaths& paths,
|
||||
const fs::path& cmake_script,
|
||||
std::vector<System::CMakeVariable>&& pass_variables);
|
||||
}
|
||||
|
@ -1,19 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <vcpkg/dependencies.h>
|
||||
#include <vcpkg/vcpkgpaths.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace vcpkg::Export::Chocolatey
|
||||
{
|
||||
struct Options
|
||||
{
|
||||
Optional<std::string> maybe_maintainer;
|
||||
Optional<std::string> maybe_version_suffix;
|
||||
};
|
||||
|
||||
void do_export(const std::vector<Dependencies::ExportPlanAction>& export_plan,
|
||||
const VcpkgPaths& paths,
|
||||
const Options& chocolatey_options);
|
||||
}
|
||||
#pragma once
|
||||
|
||||
#include <vcpkg/dependencies.h>
|
||||
#include <vcpkg/vcpkgpaths.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace vcpkg::Export::Chocolatey
|
||||
{
|
||||
struct Options
|
||||
{
|
||||
Optional<std::string> maybe_maintainer;
|
||||
Optional<std::string> maybe_version_suffix;
|
||||
};
|
||||
|
||||
void do_export(const std::vector<Dependencies::ExportPlanAction>& export_plan,
|
||||
const VcpkgPaths& paths,
|
||||
const Options& chocolatey_options);
|
||||
}
|
||||
|
@ -1,74 +1,74 @@
|
||||
#pragma once
|
||||
|
||||
#include <vcpkg/base/expected.h>
|
||||
#include <vcpkg/base/stringview.h>
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace vcpkg::PlatformExpression
|
||||
{
|
||||
// map of cmake variables and their values.
|
||||
using Context = std::unordered_map<std::string, std::string>;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct ExprImpl;
|
||||
}
|
||||
struct Expr
|
||||
{
|
||||
static Expr Identifier(StringView id);
|
||||
static Expr Not(Expr&& e);
|
||||
static Expr And(std::vector<Expr>&& exprs);
|
||||
static Expr Or(std::vector<Expr>&& exprs);
|
||||
|
||||
// The empty expression is always true
|
||||
static Expr Empty() { return Expr(); }
|
||||
|
||||
// since ExprImpl is not yet defined, we need to define the ctor and dtor in the C++ file
|
||||
Expr();
|
||||
Expr(const Expr&);
|
||||
Expr(Expr&&);
|
||||
Expr& operator=(const Expr& e);
|
||||
Expr& operator=(Expr&&);
|
||||
|
||||
explicit Expr(std::unique_ptr<detail::ExprImpl>&& e);
|
||||
~Expr();
|
||||
|
||||
bool evaluate(const Context& context) const;
|
||||
bool is_empty() const { return !static_cast<bool>(underlying_); }
|
||||
|
||||
private:
|
||||
std::unique_ptr<detail::ExprImpl> underlying_;
|
||||
};
|
||||
|
||||
// Note: for backwards compatibility, in CONTROL files,
|
||||
// multiple binary operators are allowed to be next to one another; i.e.
|
||||
// (windows & arm) = (windows && arm) = (windows &&& arm), etc.
|
||||
enum class MultipleBinaryOperators
|
||||
{
|
||||
Deny,
|
||||
Allow,
|
||||
};
|
||||
|
||||
// platform expression parses the following :
|
||||
// <platform-expression>:
|
||||
// <platform-expression.not>
|
||||
// <platform-expression.and>
|
||||
// <platform-expression.or>
|
||||
// <platform-expression.simple>:
|
||||
// ( <platform-expression> )
|
||||
// <platform-expression.identifier>
|
||||
// <platform-expression.identifier>:
|
||||
// A lowercase alpha-numeric string
|
||||
// <platform-expression.not>:
|
||||
// <platform-expression.simple>
|
||||
// ! <platform-expression.simple>
|
||||
// <platform-expression.and>
|
||||
// <platform-expression.not>
|
||||
// <platform-expression.and> & <platform-expression.not>
|
||||
// <platform-expression.or>
|
||||
// <platform-expression.not>
|
||||
// <platform-expression.or> | <platform-expression.not>
|
||||
ExpectedS<Expr> parse_platform_expression(StringView expression, MultipleBinaryOperators multiple_binary_operators);
|
||||
}
|
||||
#pragma once
|
||||
|
||||
#include <vcpkg/base/expected.h>
|
||||
#include <vcpkg/base/stringview.h>
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace vcpkg::PlatformExpression
|
||||
{
|
||||
// map of cmake variables and their values.
|
||||
using Context = std::unordered_map<std::string, std::string>;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct ExprImpl;
|
||||
}
|
||||
struct Expr
|
||||
{
|
||||
static Expr Identifier(StringView id);
|
||||
static Expr Not(Expr&& e);
|
||||
static Expr And(std::vector<Expr>&& exprs);
|
||||
static Expr Or(std::vector<Expr>&& exprs);
|
||||
|
||||
// The empty expression is always true
|
||||
static Expr Empty() { return Expr(); }
|
||||
|
||||
// since ExprImpl is not yet defined, we need to define the ctor and dtor in the C++ file
|
||||
Expr();
|
||||
Expr(const Expr&);
|
||||
Expr(Expr&&);
|
||||
Expr& operator=(const Expr& e);
|
||||
Expr& operator=(Expr&&);
|
||||
|
||||
explicit Expr(std::unique_ptr<detail::ExprImpl>&& e);
|
||||
~Expr();
|
||||
|
||||
bool evaluate(const Context& context) const;
|
||||
bool is_empty() const { return !static_cast<bool>(underlying_); }
|
||||
|
||||
private:
|
||||
std::unique_ptr<detail::ExprImpl> underlying_;
|
||||
};
|
||||
|
||||
// Note: for backwards compatibility, in CONTROL files,
|
||||
// multiple binary operators are allowed to be next to one another; i.e.
|
||||
// (windows & arm) = (windows && arm) = (windows &&& arm), etc.
|
||||
enum class MultipleBinaryOperators
|
||||
{
|
||||
Deny,
|
||||
Allow,
|
||||
};
|
||||
|
||||
// platform expression parses the following :
|
||||
// <platform-expression>:
|
||||
// <platform-expression.not>
|
||||
// <platform-expression.and>
|
||||
// <platform-expression.or>
|
||||
// <platform-expression.simple>:
|
||||
// ( <platform-expression> )
|
||||
// <platform-expression.identifier>
|
||||
// <platform-expression.identifier>:
|
||||
// A lowercase alpha-numeric string
|
||||
// <platform-expression.not>:
|
||||
// <platform-expression.simple>
|
||||
// ! <platform-expression.simple>
|
||||
// <platform-expression.and>
|
||||
// <platform-expression.not>
|
||||
// <platform-expression.and> & <platform-expression.not>
|
||||
// <platform-expression.or>
|
||||
// <platform-expression.not>
|
||||
// <platform-expression.or> | <platform-expression.not>
|
||||
ExpectedS<Expr> parse_platform_expression(StringView expression, MultipleBinaryOperators multiple_binary_operators);
|
||||
}
|
||||
|
@ -1,17 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
namespace vcpkg::Parse
|
||||
{
|
||||
struct TextRowCol
|
||||
{
|
||||
constexpr TextRowCol() noexcept = default;
|
||||
constexpr TextRowCol(int row, int column) noexcept : row(row), column(column) { }
|
||||
/// '0' indicates uninitialized; '1' is the first row.
|
||||
int row = 0;
|
||||
/// '0' indicates uninitialized; '1' is the first column.
|
||||
int column = 0;
|
||||
|
||||
constexpr int row_or(int def) const noexcept { return row ? row : def; }
|
||||
constexpr int column_or(int def) const noexcept { return column ? column : def; }
|
||||
};
|
||||
}
|
||||
#pragma once
|
||||
|
||||
namespace vcpkg::Parse
|
||||
{
|
||||
struct TextRowCol
|
||||
{
|
||||
constexpr TextRowCol() noexcept = default;
|
||||
constexpr TextRowCol(int row, int column) noexcept : row(row), column(column) { }
|
||||
/// '0' indicates uninitialized; '1' is the first row.
|
||||
int row = 0;
|
||||
/// '0' indicates uninitialized; '1' is the first column.
|
||||
int column = 0;
|
||||
|
||||
constexpr int row_or(int def) const noexcept { return row ? row : def; }
|
||||
constexpr int column_or(int def) const noexcept { return column ? column : def; }
|
||||
};
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#include <vcpkg/vcpkgpaths.h>
|
||||
|
||||
namespace vcpkg::VisualStudio
|
||||
{
|
||||
std::vector<std::string> get_visual_studio_instances(const VcpkgPaths& paths);
|
||||
|
||||
std::vector<Toolset> find_toolset_instances_preferred_first(const VcpkgPaths& paths);
|
||||
}
|
||||
|
||||
#endif
|
||||
#pragma once
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#include <vcpkg/vcpkgpaths.h>
|
||||
|
||||
namespace vcpkg::VisualStudio
|
||||
{
|
||||
std::vector<std::string> get_visual_studio_instances(const VcpkgPaths& paths);
|
||||
|
||||
std::vector<Toolset> find_toolset_instances_preferred_first(const VcpkgPaths& paths);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,28 +1,28 @@
|
||||
#include <vcpkg-test/mockcmakevarprovider.h>
|
||||
|
||||
namespace vcpkg::Test
|
||||
{
|
||||
Optional<const std::unordered_map<std::string, std::string>&> MockCMakeVarProvider::get_generic_triplet_vars(
|
||||
Triplet triplet) const
|
||||
{
|
||||
auto it = generic_triplet_vars.find(triplet);
|
||||
if (it == generic_triplet_vars.end()) return nullopt;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
Optional<const std::unordered_map<std::string, std::string>&> MockCMakeVarProvider::get_dep_info_vars(
|
||||
const PackageSpec& spec) const
|
||||
{
|
||||
auto it = dep_info_vars.find(spec);
|
||||
if (it == dep_info_vars.end()) return nullopt;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
Optional<const std::unordered_map<std::string, std::string>&> MockCMakeVarProvider::get_tag_vars(
|
||||
const PackageSpec& spec) const
|
||||
{
|
||||
auto it = tag_vars.find(spec);
|
||||
if (it == tag_vars.end()) return nullopt;
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
#include <vcpkg-test/mockcmakevarprovider.h>
|
||||
|
||||
namespace vcpkg::Test
|
||||
{
|
||||
Optional<const std::unordered_map<std::string, std::string>&> MockCMakeVarProvider::get_generic_triplet_vars(
|
||||
Triplet triplet) const
|
||||
{
|
||||
auto it = generic_triplet_vars.find(triplet);
|
||||
if (it == generic_triplet_vars.end()) return nullopt;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
Optional<const std::unordered_map<std::string, std::string>&> MockCMakeVarProvider::get_dep_info_vars(
|
||||
const PackageSpec& spec) const
|
||||
{
|
||||
auto it = dep_info_vars.find(spec);
|
||||
if (it == dep_info_vars.end()) return nullopt;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
Optional<const std::unordered_map<std::string, std::string>&> MockCMakeVarProvider::get_tag_vars(
|
||||
const PackageSpec& spec) const
|
||||
{
|
||||
auto it = tag_vars.find(spec);
|
||||
if (it == tag_vars.end()) return nullopt;
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,20 +1,20 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include <vcpkg/buildenvironment.h>
|
||||
|
||||
namespace vcpkg
|
||||
{
|
||||
std::string make_cmake_cmd(const VcpkgPaths& paths,
|
||||
const fs::path& cmake_script,
|
||||
std::vector<System::CMakeVariable>&& pass_variables)
|
||||
{
|
||||
auto local_variables = std::move(pass_variables);
|
||||
local_variables.emplace_back("VCPKG_ROOT_DIR", paths.root);
|
||||
local_variables.emplace_back("PACKAGES_DIR", paths.packages);
|
||||
local_variables.emplace_back("BUILDTREES_DIR", paths.buildtrees);
|
||||
local_variables.emplace_back("_VCPKG_INSTALLED_DIR", paths.installed);
|
||||
local_variables.emplace_back("DOWNLOADS", paths.downloads);
|
||||
local_variables.emplace_back("VCPKG_MANIFEST_INSTALL", "OFF");
|
||||
return System::make_basic_cmake_cmd(paths.get_tool_exe(Tools::CMAKE), cmake_script, local_variables);
|
||||
}
|
||||
}
|
||||
#include "pch.h"
|
||||
|
||||
#include <vcpkg/buildenvironment.h>
|
||||
|
||||
namespace vcpkg
|
||||
{
|
||||
std::string make_cmake_cmd(const VcpkgPaths& paths,
|
||||
const fs::path& cmake_script,
|
||||
std::vector<System::CMakeVariable>&& pass_variables)
|
||||
{
|
||||
auto local_variables = std::move(pass_variables);
|
||||
local_variables.emplace_back("VCPKG_ROOT_DIR", paths.root);
|
||||
local_variables.emplace_back("PACKAGES_DIR", paths.packages);
|
||||
local_variables.emplace_back("BUILDTREES_DIR", paths.buildtrees);
|
||||
local_variables.emplace_back("_VCPKG_INSTALLED_DIR", paths.installed);
|
||||
local_variables.emplace_back("DOWNLOADS", paths.downloads);
|
||||
local_variables.emplace_back("VCPKG_MANIFEST_INSTALL", "OFF");
|
||||
return System::make_basic_cmake_cmd(paths.get_tool_exe(Tools::CMAKE), cmake_script, local_variables);
|
||||
}
|
||||
}
|
||||
|
@ -1,42 +1,42 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include <vcpkg/base/checks.h>
|
||||
#include <vcpkg/base/files.h>
|
||||
#include <vcpkg/base/system.print.h>
|
||||
|
||||
#include <vcpkg/commands.h>
|
||||
#include <vcpkg/vcpkgcmdarguments.h>
|
||||
|
||||
using namespace vcpkg;
|
||||
|
||||
namespace
|
||||
{
|
||||
void clear_directory(Files::Filesystem& fs, const fs::path& target)
|
||||
{
|
||||
using vcpkg::System::print2;
|
||||
if (fs.is_directory(target))
|
||||
{
|
||||
print2("Clearing contents of ", target.u8string(), "\n");
|
||||
fs.remove_all_inside(target, VCPKG_LINE_INFO);
|
||||
}
|
||||
else
|
||||
{
|
||||
print2("Skipping clearing contents of ", target.u8string(), " because it was not a directory\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace vcpkg::Commands::CIClean
|
||||
{
|
||||
void perform_and_exit(const VcpkgCmdArguments&, const VcpkgPaths& paths)
|
||||
{
|
||||
using vcpkg::System::print2;
|
||||
auto& fs = paths.get_filesystem();
|
||||
print2("Starting vcpkg CI clean\n");
|
||||
clear_directory(fs, paths.buildtrees);
|
||||
clear_directory(fs, paths.installed);
|
||||
clear_directory(fs, paths.packages);
|
||||
print2("Completed vcpkg CI clean\n");
|
||||
Checks::exit_success(VCPKG_LINE_INFO);
|
||||
}
|
||||
}
|
||||
#include "pch.h"
|
||||
|
||||
#include <vcpkg/base/checks.h>
|
||||
#include <vcpkg/base/files.h>
|
||||
#include <vcpkg/base/system.print.h>
|
||||
|
||||
#include <vcpkg/commands.h>
|
||||
#include <vcpkg/vcpkgcmdarguments.h>
|
||||
|
||||
using namespace vcpkg;
|
||||
|
||||
namespace
|
||||
{
|
||||
void clear_directory(Files::Filesystem& fs, const fs::path& target)
|
||||
{
|
||||
using vcpkg::System::print2;
|
||||
if (fs.is_directory(target))
|
||||
{
|
||||
print2("Clearing contents of ", target.u8string(), "\n");
|
||||
fs.remove_all_inside(target, VCPKG_LINE_INFO);
|
||||
}
|
||||
else
|
||||
{
|
||||
print2("Skipping clearing contents of ", target.u8string(), " because it was not a directory\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace vcpkg::Commands::CIClean
|
||||
{
|
||||
void perform_and_exit(const VcpkgCmdArguments&, const VcpkgPaths& paths)
|
||||
{
|
||||
using vcpkg::System::print2;
|
||||
auto& fs = paths.get_filesystem();
|
||||
print2("Starting vcpkg CI clean\n");
|
||||
clear_directory(fs, paths.buildtrees);
|
||||
clear_directory(fs, paths.installed);
|
||||
clear_directory(fs, paths.packages);
|
||||
print2("Completed vcpkg CI clean\n");
|
||||
Checks::exit_success(VCPKG_LINE_INFO);
|
||||
}
|
||||
}
|
||||
|
@ -1,331 +1,331 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include <vcpkg/base/strings.h>
|
||||
#include <vcpkg/base/system.print.h>
|
||||
#include <vcpkg/base/util.h>
|
||||
|
||||
#include <vcpkg/commands.h>
|
||||
#include <vcpkg/dependencies.h>
|
||||
#include <vcpkg/help.h>
|
||||
#include <vcpkg/input.h>
|
||||
#include <vcpkg/install.h>
|
||||
#include <vcpkg/packagespec.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
using vcpkg::Dependencies::ActionPlan;
|
||||
using vcpkg::Dependencies::InstallPlanAction;
|
||||
using vcpkg::PortFileProvider::PathsPortFileProvider;
|
||||
|
||||
namespace vcpkg::Commands::DependInfo
|
||||
{
|
||||
namespace
|
||||
{
|
||||
constexpr StringLiteral OPTION_DOT = "--dot";
|
||||
constexpr StringLiteral OPTION_DGML = "--dgml";
|
||||
constexpr StringLiteral OPTION_SHOW_DEPTH = "--show-depth";
|
||||
constexpr StringLiteral OPTION_MAX_RECURSE = "--max-recurse";
|
||||
constexpr StringLiteral OPTION_SORT = "--sort";
|
||||
|
||||
constexpr int NO_RECURSE_LIMIT_VALUE = -1;
|
||||
|
||||
constexpr std::array<CommandSwitch, 3> DEPEND_SWITCHES = {
|
||||
{{OPTION_DOT, "Creates graph on basis of dot"},
|
||||
{OPTION_DGML, "Creates graph on basis of dgml"},
|
||||
{OPTION_SHOW_DEPTH, "Show recursion depth in output"}}};
|
||||
|
||||
constexpr std::array<CommandSetting, 2> DEPEND_SETTINGS = {
|
||||
{{OPTION_MAX_RECURSE, "Set max recursion depth, a value of -1 indicates no limit"},
|
||||
{OPTION_SORT,
|
||||
"Set sort order for the list of dependencies, accepted values are: lexicographical, topological "
|
||||
"(default), "
|
||||
"reverse"}}};
|
||||
|
||||
struct PackageDependInfo
|
||||
{
|
||||
std::string package;
|
||||
int depth;
|
||||
std::unordered_set<std::string> features;
|
||||
std::vector<std::string> dependencies;
|
||||
};
|
||||
|
||||
enum SortMode
|
||||
{
|
||||
Lexicographical = 0,
|
||||
Topological,
|
||||
ReverseTopological,
|
||||
Default = Topological
|
||||
};
|
||||
|
||||
int get_max_depth(const ParsedArguments& options)
|
||||
{
|
||||
auto iter = options.settings.find(OPTION_MAX_RECURSE);
|
||||
if (iter != options.settings.end())
|
||||
{
|
||||
std::string value = iter->second;
|
||||
try
|
||||
{
|
||||
return std::stoi(value);
|
||||
}
|
||||
catch (std::exception&)
|
||||
{
|
||||
Checks::exit_with_message(VCPKG_LINE_INFO, "Value of --max-depth must be an integer");
|
||||
}
|
||||
}
|
||||
// No --max-depth set, default to no limit.
|
||||
return NO_RECURSE_LIMIT_VALUE;
|
||||
}
|
||||
|
||||
SortMode get_sort_mode(const ParsedArguments& options)
|
||||
{
|
||||
constexpr StringLiteral OPTION_SORT_LEXICOGRAPHICAL = "lexicographical";
|
||||
constexpr StringLiteral OPTION_SORT_TOPOLOGICAL = "topological";
|
||||
constexpr StringLiteral OPTION_SORT_REVERSE = "reverse";
|
||||
|
||||
static const std::map<std::string, SortMode> sortModesMap{{OPTION_SORT_LEXICOGRAPHICAL, Lexicographical},
|
||||
{OPTION_SORT_TOPOLOGICAL, Topological},
|
||||
{OPTION_SORT_REVERSE, ReverseTopological}};
|
||||
|
||||
auto iter = options.settings.find(OPTION_SORT);
|
||||
if (iter != options.settings.end())
|
||||
{
|
||||
const std::string value = Strings::ascii_to_lowercase(std::string{iter->second});
|
||||
auto it = sortModesMap.find(value);
|
||||
if (it != sortModesMap.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
Checks::exit_with_message(VCPKG_LINE_INFO,
|
||||
"Value of --sort must be one of `%s`, `%s`, or `%s`",
|
||||
OPTION_SORT_LEXICOGRAPHICAL,
|
||||
OPTION_SORT_TOPOLOGICAL,
|
||||
OPTION_SORT_REVERSE);
|
||||
}
|
||||
return Default;
|
||||
}
|
||||
|
||||
std::string create_dot_as_string(const std::vector<PackageDependInfo>& depend_info)
|
||||
{
|
||||
int empty_node_count = 0;
|
||||
|
||||
std::string s;
|
||||
s.append("digraph G{ rankdir=LR; edge [minlen=3]; overlap=false;");
|
||||
|
||||
for (const auto& package : depend_info)
|
||||
{
|
||||
if (package.dependencies.empty())
|
||||
{
|
||||
empty_node_count++;
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::string name = Strings::replace_all(std::string{package.package}, "-", "_");
|
||||
s.append(Strings::format("%s;", name));
|
||||
for (const auto& d : package.dependencies)
|
||||
{
|
||||
const std::string dependency_name = Strings::replace_all(std::string{d}, "-", "_");
|
||||
s.append(Strings::format("%s -> %s;", name, dependency_name));
|
||||
}
|
||||
}
|
||||
|
||||
s.append(Strings::format("empty [label=\"%d singletons...\"]; }", empty_node_count));
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string create_dgml_as_string(const std::vector<PackageDependInfo>& depend_info)
|
||||
{
|
||||
std::string s;
|
||||
s.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
|
||||
s.append("<DirectedGraph xmlns=\"http://schemas.microsoft.com/vs/2009/dgml\">");
|
||||
|
||||
std::string nodes, links;
|
||||
for (const auto& package : depend_info)
|
||||
{
|
||||
const std::string name = package.package;
|
||||
nodes.append(Strings::format("<Node Id=\"%s\" />", name));
|
||||
|
||||
// Iterate over dependencies.
|
||||
for (const auto& d : package.dependencies)
|
||||
{
|
||||
links.append(Strings::format("<Link Source=\"%s\" Target=\"%s\" />", name, d));
|
||||
}
|
||||
}
|
||||
|
||||
s.append(Strings::format("<Nodes>%s</Nodes>", nodes));
|
||||
|
||||
s.append(Strings::format("<Links>%s</Links>", links));
|
||||
|
||||
s.append("</DirectedGraph>");
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string create_graph_as_string(const std::unordered_set<std::string>& switches,
|
||||
const std::vector<PackageDependInfo>& depend_info)
|
||||
{
|
||||
if (Util::Sets::contains(switches, OPTION_DOT))
|
||||
{
|
||||
return create_dot_as_string(depend_info);
|
||||
}
|
||||
else if (Util::Sets::contains(switches, OPTION_DGML))
|
||||
{
|
||||
return create_dgml_as_string(depend_info);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void assign_depth_to_dependencies(const std::string& package,
|
||||
const int depth,
|
||||
const int max_depth,
|
||||
std::map<std::string, PackageDependInfo>& dependencies_map)
|
||||
{
|
||||
auto iter = dependencies_map.find(package);
|
||||
Checks::check_exit(
|
||||
VCPKG_LINE_INFO, iter != dependencies_map.end(), "Package not found in dependency graph");
|
||||
|
||||
PackageDependInfo& info = iter->second;
|
||||
|
||||
if (depth > info.depth)
|
||||
{
|
||||
info.depth = depth;
|
||||
if (depth < max_depth || max_depth == NO_RECURSE_LIMIT_VALUE)
|
||||
{
|
||||
for (auto&& dependency : info.dependencies)
|
||||
{
|
||||
assign_depth_to_dependencies(dependency, depth + 1, max_depth, dependencies_map);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<PackageDependInfo> extract_depend_info(const std::vector<const InstallPlanAction*>& install_actions,
|
||||
const int max_depth)
|
||||
{
|
||||
std::map<std::string, PackageDependInfo> package_dependencies;
|
||||
for (const InstallPlanAction* pia : install_actions)
|
||||
{
|
||||
const InstallPlanAction& install_action = *pia;
|
||||
|
||||
const std::vector<std::string> dependencies = Util::fmap(
|
||||
install_action.package_dependencies, [](const PackageSpec& spec) { return spec.name(); });
|
||||
|
||||
std::unordered_set<std::string> features{install_action.feature_list.begin(),
|
||||
install_action.feature_list.end()};
|
||||
features.erase("core");
|
||||
|
||||
std::string port_name = install_action.spec.name();
|
||||
|
||||
PackageDependInfo info{port_name, -1, features, dependencies};
|
||||
package_dependencies.emplace(port_name, std::move(info));
|
||||
}
|
||||
|
||||
const InstallPlanAction& init = *install_actions.back();
|
||||
assign_depth_to_dependencies(init.spec.name(), 0, max_depth, package_dependencies);
|
||||
|
||||
std::vector<PackageDependInfo> out =
|
||||
Util::fmap(package_dependencies, [](auto&& kvpair) -> PackageDependInfo { return kvpair.second; });
|
||||
Util::erase_remove_if(out, [](auto&& info) { return info.depth < 0; });
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
const CommandStructure COMMAND_STRUCTURE = {
|
||||
create_example_string("depend-info sqlite3"),
|
||||
1,
|
||||
1,
|
||||
{DEPEND_SWITCHES, DEPEND_SETTINGS},
|
||||
nullptr,
|
||||
};
|
||||
|
||||
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet)
|
||||
{
|
||||
const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
|
||||
const int max_depth = get_max_depth(options);
|
||||
const SortMode sort_mode = get_sort_mode(options);
|
||||
const bool show_depth = Util::Sets::contains(options.switches, OPTION_SHOW_DEPTH);
|
||||
|
||||
const std::vector<FullPackageSpec> specs = Util::fmap(args.command_arguments, [&](auto&& arg) {
|
||||
return Input::check_and_get_full_package_spec(
|
||||
std::string{arg}, default_triplet, COMMAND_STRUCTURE.example_text);
|
||||
});
|
||||
|
||||
for (auto&& spec : specs)
|
||||
{
|
||||
Input::check_triplet(spec.package_spec.triplet(), paths);
|
||||
}
|
||||
|
||||
PathsPortFileProvider provider(paths, args.overlay_ports);
|
||||
auto var_provider_storage = CMakeVars::make_triplet_cmake_var_provider(paths);
|
||||
auto& var_provider = *var_provider_storage;
|
||||
|
||||
// By passing an empty status_db, we should get a plan containing all dependencies.
|
||||
// All actions in the plan should be install actions, as there's no installed packages to remove.
|
||||
StatusParagraphs status_db;
|
||||
auto action_plan = Dependencies::create_feature_install_plan(provider, var_provider, specs, status_db);
|
||||
Checks::check_exit(
|
||||
VCPKG_LINE_INFO, action_plan.remove_actions.empty(), "Only install actions should exist in the plan");
|
||||
std::vector<const InstallPlanAction*> install_actions =
|
||||
Util::fmap(action_plan.already_installed, [&](const auto& action) { return &action; });
|
||||
for (auto&& action : action_plan.install_actions)
|
||||
install_actions.push_back(&action);
|
||||
|
||||
std::vector<PackageDependInfo> depend_info = extract_depend_info(install_actions, max_depth);
|
||||
|
||||
if (Util::Sets::contains(options.switches, OPTION_DOT) || Util::Sets::contains(options.switches, OPTION_DGML))
|
||||
{
|
||||
const std::vector<const SourceControlFile*> source_control_files =
|
||||
Util::fmap(install_actions, [](const InstallPlanAction* install_action) {
|
||||
const SourceControlFileLocation& scfl =
|
||||
install_action->source_control_file_location.value_or_exit(VCPKG_LINE_INFO);
|
||||
return const_cast<const SourceControlFile*>(scfl.source_control_file.get());
|
||||
});
|
||||
|
||||
const std::string graph_as_string = create_graph_as_string(options.switches, depend_info);
|
||||
System::print2(graph_as_string, '\n');
|
||||
Checks::exit_success(VCPKG_LINE_INFO);
|
||||
}
|
||||
|
||||
// TODO: Improve this code
|
||||
auto lex = [](const PackageDependInfo& lhs, const PackageDependInfo& rhs) -> bool {
|
||||
return lhs.package < rhs.package;
|
||||
};
|
||||
auto topo = [](const PackageDependInfo& lhs, const PackageDependInfo& rhs) -> bool {
|
||||
return lhs.depth > rhs.depth;
|
||||
};
|
||||
auto reverse = [](const PackageDependInfo& lhs, const PackageDependInfo& rhs) -> bool {
|
||||
return lhs.depth < rhs.depth;
|
||||
};
|
||||
|
||||
switch (sort_mode)
|
||||
{
|
||||
case SortMode::Lexicographical: std::sort(std::begin(depend_info), std::end(depend_info), lex); break;
|
||||
case SortMode::ReverseTopological:
|
||||
std::sort(std::begin(depend_info), std::end(depend_info), reverse);
|
||||
break;
|
||||
case SortMode::Topological: std::sort(std::begin(depend_info), std::end(depend_info), topo); break;
|
||||
default: Checks::unreachable(VCPKG_LINE_INFO);
|
||||
}
|
||||
|
||||
for (auto&& info : depend_info)
|
||||
{
|
||||
if (info.depth >= 0)
|
||||
{
|
||||
std::string features = Strings::join(", ", info.features);
|
||||
const std::string dependencies = Strings::join(", ", info.dependencies);
|
||||
|
||||
if (show_depth)
|
||||
{
|
||||
System::print2(System::Color::error, "(", info.depth, ") ");
|
||||
}
|
||||
System::print2(System::Color::success, info.package);
|
||||
if (!features.empty())
|
||||
{
|
||||
System::print2("[");
|
||||
System::print2(System::Color::warning, features);
|
||||
System::print2("]");
|
||||
}
|
||||
System::print2(": ", dependencies, "\n");
|
||||
}
|
||||
}
|
||||
Checks::exit_success(VCPKG_LINE_INFO);
|
||||
}
|
||||
}
|
||||
#include "pch.h"
|
||||
|
||||
#include <vcpkg/base/strings.h>
|
||||
#include <vcpkg/base/system.print.h>
|
||||
#include <vcpkg/base/util.h>
|
||||
|
||||
#include <vcpkg/commands.h>
|
||||
#include <vcpkg/dependencies.h>
|
||||
#include <vcpkg/help.h>
|
||||
#include <vcpkg/input.h>
|
||||
#include <vcpkg/install.h>
|
||||
#include <vcpkg/packagespec.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
using vcpkg::Dependencies::ActionPlan;
|
||||
using vcpkg::Dependencies::InstallPlanAction;
|
||||
using vcpkg::PortFileProvider::PathsPortFileProvider;
|
||||
|
||||
namespace vcpkg::Commands::DependInfo
|
||||
{
|
||||
namespace
|
||||
{
|
||||
constexpr StringLiteral OPTION_DOT = "--dot";
|
||||
constexpr StringLiteral OPTION_DGML = "--dgml";
|
||||
constexpr StringLiteral OPTION_SHOW_DEPTH = "--show-depth";
|
||||
constexpr StringLiteral OPTION_MAX_RECURSE = "--max-recurse";
|
||||
constexpr StringLiteral OPTION_SORT = "--sort";
|
||||
|
||||
constexpr int NO_RECURSE_LIMIT_VALUE = -1;
|
||||
|
||||
constexpr std::array<CommandSwitch, 3> DEPEND_SWITCHES = {
|
||||
{{OPTION_DOT, "Creates graph on basis of dot"},
|
||||
{OPTION_DGML, "Creates graph on basis of dgml"},
|
||||
{OPTION_SHOW_DEPTH, "Show recursion depth in output"}}};
|
||||
|
||||
constexpr std::array<CommandSetting, 2> DEPEND_SETTINGS = {
|
||||
{{OPTION_MAX_RECURSE, "Set max recursion depth, a value of -1 indicates no limit"},
|
||||
{OPTION_SORT,
|
||||
"Set sort order for the list of dependencies, accepted values are: lexicographical, topological "
|
||||
"(default), "
|
||||
"reverse"}}};
|
||||
|
||||
struct PackageDependInfo
|
||||
{
|
||||
std::string package;
|
||||
int depth;
|
||||
std::unordered_set<std::string> features;
|
||||
std::vector<std::string> dependencies;
|
||||
};
|
||||
|
||||
enum SortMode
|
||||
{
|
||||
Lexicographical = 0,
|
||||
Topological,
|
||||
ReverseTopological,
|
||||
Default = Topological
|
||||
};
|
||||
|
||||
int get_max_depth(const ParsedArguments& options)
|
||||
{
|
||||
auto iter = options.settings.find(OPTION_MAX_RECURSE);
|
||||
if (iter != options.settings.end())
|
||||
{
|
||||
std::string value = iter->second;
|
||||
try
|
||||
{
|
||||
return std::stoi(value);
|
||||
}
|
||||
catch (std::exception&)
|
||||
{
|
||||
Checks::exit_with_message(VCPKG_LINE_INFO, "Value of --max-depth must be an integer");
|
||||
}
|
||||
}
|
||||
// No --max-depth set, default to no limit.
|
||||
return NO_RECURSE_LIMIT_VALUE;
|
||||
}
|
||||
|
||||
SortMode get_sort_mode(const ParsedArguments& options)
|
||||
{
|
||||
constexpr StringLiteral OPTION_SORT_LEXICOGRAPHICAL = "lexicographical";
|
||||
constexpr StringLiteral OPTION_SORT_TOPOLOGICAL = "topological";
|
||||
constexpr StringLiteral OPTION_SORT_REVERSE = "reverse";
|
||||
|
||||
static const std::map<std::string, SortMode> sortModesMap{{OPTION_SORT_LEXICOGRAPHICAL, Lexicographical},
|
||||
{OPTION_SORT_TOPOLOGICAL, Topological},
|
||||
{OPTION_SORT_REVERSE, ReverseTopological}};
|
||||
|
||||
auto iter = options.settings.find(OPTION_SORT);
|
||||
if (iter != options.settings.end())
|
||||
{
|
||||
const std::string value = Strings::ascii_to_lowercase(std::string{iter->second});
|
||||
auto it = sortModesMap.find(value);
|
||||
if (it != sortModesMap.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
Checks::exit_with_message(VCPKG_LINE_INFO,
|
||||
"Value of --sort must be one of `%s`, `%s`, or `%s`",
|
||||
OPTION_SORT_LEXICOGRAPHICAL,
|
||||
OPTION_SORT_TOPOLOGICAL,
|
||||
OPTION_SORT_REVERSE);
|
||||
}
|
||||
return Default;
|
||||
}
|
||||
|
||||
std::string create_dot_as_string(const std::vector<PackageDependInfo>& depend_info)
|
||||
{
|
||||
int empty_node_count = 0;
|
||||
|
||||
std::string s;
|
||||
s.append("digraph G{ rankdir=LR; edge [minlen=3]; overlap=false;");
|
||||
|
||||
for (const auto& package : depend_info)
|
||||
{
|
||||
if (package.dependencies.empty())
|
||||
{
|
||||
empty_node_count++;
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::string name = Strings::replace_all(std::string{package.package}, "-", "_");
|
||||
s.append(Strings::format("%s;", name));
|
||||
for (const auto& d : package.dependencies)
|
||||
{
|
||||
const std::string dependency_name = Strings::replace_all(std::string{d}, "-", "_");
|
||||
s.append(Strings::format("%s -> %s;", name, dependency_name));
|
||||
}
|
||||
}
|
||||
|
||||
s.append(Strings::format("empty [label=\"%d singletons...\"]; }", empty_node_count));
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string create_dgml_as_string(const std::vector<PackageDependInfo>& depend_info)
|
||||
{
|
||||
std::string s;
|
||||
s.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
|
||||
s.append("<DirectedGraph xmlns=\"http://schemas.microsoft.com/vs/2009/dgml\">");
|
||||
|
||||
std::string nodes, links;
|
||||
for (const auto& package : depend_info)
|
||||
{
|
||||
const std::string name = package.package;
|
||||
nodes.append(Strings::format("<Node Id=\"%s\" />", name));
|
||||
|
||||
// Iterate over dependencies.
|
||||
for (const auto& d : package.dependencies)
|
||||
{
|
||||
links.append(Strings::format("<Link Source=\"%s\" Target=\"%s\" />", name, d));
|
||||
}
|
||||
}
|
||||
|
||||
s.append(Strings::format("<Nodes>%s</Nodes>", nodes));
|
||||
|
||||
s.append(Strings::format("<Links>%s</Links>", links));
|
||||
|
||||
s.append("</DirectedGraph>");
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string create_graph_as_string(const std::unordered_set<std::string>& switches,
|
||||
const std::vector<PackageDependInfo>& depend_info)
|
||||
{
|
||||
if (Util::Sets::contains(switches, OPTION_DOT))
|
||||
{
|
||||
return create_dot_as_string(depend_info);
|
||||
}
|
||||
else if (Util::Sets::contains(switches, OPTION_DGML))
|
||||
{
|
||||
return create_dgml_as_string(depend_info);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void assign_depth_to_dependencies(const std::string& package,
|
||||
const int depth,
|
||||
const int max_depth,
|
||||
std::map<std::string, PackageDependInfo>& dependencies_map)
|
||||
{
|
||||
auto iter = dependencies_map.find(package);
|
||||
Checks::check_exit(
|
||||
VCPKG_LINE_INFO, iter != dependencies_map.end(), "Package not found in dependency graph");
|
||||
|
||||
PackageDependInfo& info = iter->second;
|
||||
|
||||
if (depth > info.depth)
|
||||
{
|
||||
info.depth = depth;
|
||||
if (depth < max_depth || max_depth == NO_RECURSE_LIMIT_VALUE)
|
||||
{
|
||||
for (auto&& dependency : info.dependencies)
|
||||
{
|
||||
assign_depth_to_dependencies(dependency, depth + 1, max_depth, dependencies_map);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<PackageDependInfo> extract_depend_info(const std::vector<const InstallPlanAction*>& install_actions,
|
||||
const int max_depth)
|
||||
{
|
||||
std::map<std::string, PackageDependInfo> package_dependencies;
|
||||
for (const InstallPlanAction* pia : install_actions)
|
||||
{
|
||||
const InstallPlanAction& install_action = *pia;
|
||||
|
||||
const std::vector<std::string> dependencies = Util::fmap(
|
||||
install_action.package_dependencies, [](const PackageSpec& spec) { return spec.name(); });
|
||||
|
||||
std::unordered_set<std::string> features{install_action.feature_list.begin(),
|
||||
install_action.feature_list.end()};
|
||||
features.erase("core");
|
||||
|
||||
std::string port_name = install_action.spec.name();
|
||||
|
||||
PackageDependInfo info{port_name, -1, features, dependencies};
|
||||
package_dependencies.emplace(port_name, std::move(info));
|
||||
}
|
||||
|
||||
const InstallPlanAction& init = *install_actions.back();
|
||||
assign_depth_to_dependencies(init.spec.name(), 0, max_depth, package_dependencies);
|
||||
|
||||
std::vector<PackageDependInfo> out =
|
||||
Util::fmap(package_dependencies, [](auto&& kvpair) -> PackageDependInfo { return kvpair.second; });
|
||||
Util::erase_remove_if(out, [](auto&& info) { return info.depth < 0; });
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
const CommandStructure COMMAND_STRUCTURE = {
|
||||
create_example_string("depend-info sqlite3"),
|
||||
1,
|
||||
1,
|
||||
{DEPEND_SWITCHES, DEPEND_SETTINGS},
|
||||
nullptr,
|
||||
};
|
||||
|
||||
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, Triplet default_triplet)
|
||||
{
|
||||
const ParsedArguments options = args.parse_arguments(COMMAND_STRUCTURE);
|
||||
const int max_depth = get_max_depth(options);
|
||||
const SortMode sort_mode = get_sort_mode(options);
|
||||
const bool show_depth = Util::Sets::contains(options.switches, OPTION_SHOW_DEPTH);
|
||||
|
||||
const std::vector<FullPackageSpec> specs = Util::fmap(args.command_arguments, [&](auto&& arg) {
|
||||
return Input::check_and_get_full_package_spec(
|
||||
std::string{arg}, default_triplet, COMMAND_STRUCTURE.example_text);
|
||||
});
|
||||
|
||||
for (auto&& spec : specs)
|
||||
{
|
||||
Input::check_triplet(spec.package_spec.triplet(), paths);
|
||||
}
|
||||
|
||||
PathsPortFileProvider provider(paths, args.overlay_ports);
|
||||
auto var_provider_storage = CMakeVars::make_triplet_cmake_var_provider(paths);
|
||||
auto& var_provider = *var_provider_storage;
|
||||
|
||||
// By passing an empty status_db, we should get a plan containing all dependencies.
|
||||
// All actions in the plan should be install actions, as there's no installed packages to remove.
|
||||
StatusParagraphs status_db;
|
||||
auto action_plan = Dependencies::create_feature_install_plan(provider, var_provider, specs, status_db);
|
||||
Checks::check_exit(
|
||||
VCPKG_LINE_INFO, action_plan.remove_actions.empty(), "Only install actions should exist in the plan");
|
||||
std::vector<const InstallPlanAction*> install_actions =
|
||||
Util::fmap(action_plan.already_installed, [&](const auto& action) { return &action; });
|
||||
for (auto&& action : action_plan.install_actions)
|
||||
install_actions.push_back(&action);
|
||||
|
||||
std::vector<PackageDependInfo> depend_info = extract_depend_info(install_actions, max_depth);
|
||||
|
||||
if (Util::Sets::contains(options.switches, OPTION_DOT) || Util::Sets::contains(options.switches, OPTION_DGML))
|
||||
{
|
||||
const std::vector<const SourceControlFile*> source_control_files =
|
||||
Util::fmap(install_actions, [](const InstallPlanAction* install_action) {
|
||||
const SourceControlFileLocation& scfl =
|
||||
install_action->source_control_file_location.value_or_exit(VCPKG_LINE_INFO);
|
||||
return const_cast<const SourceControlFile*>(scfl.source_control_file.get());
|
||||
});
|
||||
|
||||
const std::string graph_as_string = create_graph_as_string(options.switches, depend_info);
|
||||
System::print2(graph_as_string, '\n');
|
||||
Checks::exit_success(VCPKG_LINE_INFO);
|
||||
}
|
||||
|
||||
// TODO: Improve this code
|
||||
auto lex = [](const PackageDependInfo& lhs, const PackageDependInfo& rhs) -> bool {
|
||||
return lhs.package < rhs.package;
|
||||
};
|
||||
auto topo = [](const PackageDependInfo& lhs, const PackageDependInfo& rhs) -> bool {
|
||||
return lhs.depth > rhs.depth;
|
||||
};
|
||||
auto reverse = [](const PackageDependInfo& lhs, const PackageDependInfo& rhs) -> bool {
|
||||
return lhs.depth < rhs.depth;
|
||||
};
|
||||
|
||||
switch (sort_mode)
|
||||
{
|
||||
case SortMode::Lexicographical: std::sort(std::begin(depend_info), std::end(depend_info), lex); break;
|
||||
case SortMode::ReverseTopological:
|
||||
std::sort(std::begin(depend_info), std::end(depend_info), reverse);
|
||||
break;
|
||||
case SortMode::Topological: std::sort(std::begin(depend_info), std::end(depend_info), topo); break;
|
||||
default: Checks::unreachable(VCPKG_LINE_INFO);
|
||||
}
|
||||
|
||||
for (auto&& info : depend_info)
|
||||
{
|
||||
if (info.depth >= 0)
|
||||
{
|
||||
std::string features = Strings::join(", ", info.features);
|
||||
const std::string dependencies = Strings::join(", ", info.dependencies);
|
||||
|
||||
if (show_depth)
|
||||
{
|
||||
System::print2(System::Color::error, "(", info.depth, ") ");
|
||||
}
|
||||
System::print2(System::Color::success, info.package);
|
||||
if (!features.empty())
|
||||
{
|
||||
System::print2("[");
|
||||
System::print2(System::Color::warning, features);
|
||||
System::print2("]");
|
||||
}
|
||||
System::print2(": ", dependencies, "\n");
|
||||
}
|
||||
}
|
||||
Checks::exit_success(VCPKG_LINE_INFO);
|
||||
}
|
||||
}
|
||||
|
@ -1,36 +1,36 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include <vcpkg/base/system.print.h>
|
||||
|
||||
#include <vcpkg/commands.h>
|
||||
#include <vcpkg/help.h>
|
||||
#include <vcpkg/visualstudio.h>
|
||||
|
||||
namespace vcpkg::Commands::X_VSInstances
|
||||
{
|
||||
const CommandStructure COMMAND_STRUCTURE = {
|
||||
create_example_string("x-vsinstances"),
|
||||
0,
|
||||
0,
|
||||
{{}, {}},
|
||||
nullptr,
|
||||
};
|
||||
|
||||
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
const ParsedArguments parsed_args = args.parse_arguments(COMMAND_STRUCTURE);
|
||||
|
||||
const auto instances = vcpkg::VisualStudio::get_visual_studio_instances(paths);
|
||||
for (const std::string& instance : instances)
|
||||
{
|
||||
System::print2(instance, '\n');
|
||||
}
|
||||
|
||||
Checks::exit_success(VCPKG_LINE_INFO);
|
||||
#else
|
||||
Util::unused(args, paths);
|
||||
Checks::exit_with_message(VCPKG_LINE_INFO, "This command is not supported on non-windows platforms.");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#include "pch.h"
|
||||
|
||||
#include <vcpkg/base/system.print.h>
|
||||
|
||||
#include <vcpkg/commands.h>
|
||||
#include <vcpkg/help.h>
|
||||
#include <vcpkg/visualstudio.h>
|
||||
|
||||
namespace vcpkg::Commands::X_VSInstances
|
||||
{
|
||||
const CommandStructure COMMAND_STRUCTURE = {
|
||||
create_example_string("x-vsinstances"),
|
||||
0,
|
||||
0,
|
||||
{{}, {}},
|
||||
nullptr,
|
||||
};
|
||||
|
||||
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
const ParsedArguments parsed_args = args.parse_arguments(COMMAND_STRUCTURE);
|
||||
|
||||
const auto instances = vcpkg::VisualStudio::get_visual_studio_instances(paths);
|
||||
for (const std::string& instance : instances)
|
||||
{
|
||||
System::print2(instance, '\n');
|
||||
}
|
||||
|
||||
Checks::exit_success(VCPKG_LINE_INFO);
|
||||
#else
|
||||
Util::unused(args, paths);
|
||||
Checks::exit_with_message(VCPKG_LINE_INFO, "This command is not supported on non-windows platforms.");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -1,44 +1,44 @@
|
||||
#include "pch.h"
|
||||
|
||||
#include <vcpkg/base/system.print.h>
|
||||
#include <vcpkg/base/system.process.h>
|
||||
|
||||
#include <vcpkg/commands.h>
|
||||
#include <vcpkg/export.chocolatey.h>
|
||||
#include <vcpkg/export.h>
|
||||
#include <vcpkg/install.h>
|
||||
|
||||
namespace vcpkg::Export::Chocolatey
|
||||
{
|
||||
using Dependencies::ExportPlanAction;
|
||||
using Dependencies::ExportPlanType;
|
||||
using Install::InstallDir;
|
||||
|
||||
static std::string create_nuspec_dependencies(const BinaryParagraph& binary_paragraph,
|
||||
const std::map<std::string, std::string>& packages_version)
|
||||
{
|
||||
static constexpr auto CONTENT_TEMPLATE = R"(<dependency id="@PACKAGE_ID@" version="[@PACKAGE_VERSION@]" />)";
|
||||
|
||||
std::string nuspec_dependencies;
|
||||
for (const std::string& depend : binary_paragraph.dependencies)
|
||||
{
|
||||
auto found = packages_version.find(depend);
|
||||
if (found == packages_version.end())
|
||||
{
|
||||
Checks::exit_with_message(VCPKG_LINE_INFO, "Cannot find desired dependency version.");
|
||||
}
|
||||
std::string nuspec_dependency = Strings::replace_all(CONTENT_TEMPLATE, "@PACKAGE_ID@", depend);
|
||||
nuspec_dependency = Strings::replace_all(std::move(nuspec_dependency), "@PACKAGE_VERSION@", found->second);
|
||||
nuspec_dependencies += nuspec_dependency;
|
||||
}
|
||||
return nuspec_dependencies;
|
||||
}
|
||||
|
||||
static std::string create_nuspec_file_contents(const std::string& exported_root_dir,
|
||||
const BinaryParagraph& binary_paragraph,
|
||||
const std::map<std::string, std::string>& packages_version,
|
||||
const Options& chocolatey_options)
|
||||
{
|
||||
#include "pch.h"
|
||||
|
||||
#include <vcpkg/base/system.print.h>
|
||||
#include <vcpkg/base/system.process.h>
|
||||
|
||||
#include <vcpkg/commands.h>
|
||||
#include <vcpkg/export.chocolatey.h>
|
||||
#include <vcpkg/export.h>
|
||||
#include <vcpkg/install.h>
|
||||
|
||||
namespace vcpkg::Export::Chocolatey
|
||||
{
|
||||
using Dependencies::ExportPlanAction;
|
||||
using Dependencies::ExportPlanType;
|
||||
using Install::InstallDir;
|
||||
|
||||
static std::string create_nuspec_dependencies(const BinaryParagraph& binary_paragraph,
|
||||
const std::map<std::string, std::string>& packages_version)
|
||||
{
|
||||
static constexpr auto CONTENT_TEMPLATE = R"(<dependency id="@PACKAGE_ID@" version="[@PACKAGE_VERSION@]" />)";
|
||||
|
||||
std::string nuspec_dependencies;
|
||||
for (const std::string& depend : binary_paragraph.dependencies)
|
||||
{
|
||||
auto found = packages_version.find(depend);
|
||||
if (found == packages_version.end())
|
||||
{
|
||||
Checks::exit_with_message(VCPKG_LINE_INFO, "Cannot find desired dependency version.");
|
||||
}
|
||||
std::string nuspec_dependency = Strings::replace_all(CONTENT_TEMPLATE, "@PACKAGE_ID@", depend);
|
||||
nuspec_dependency = Strings::replace_all(std::move(nuspec_dependency), "@PACKAGE_VERSION@", found->second);
|
||||
nuspec_dependencies += nuspec_dependency;
|
||||
}
|
||||
return nuspec_dependencies;
|
||||
}
|
||||
|
||||
static std::string create_nuspec_file_contents(const std::string& exported_root_dir,
|
||||
const BinaryParagraph& binary_paragraph,
|
||||
const std::map<std::string, std::string>& packages_version,
|
||||
const Options& chocolatey_options)
|
||||
{
|
||||
static constexpr auto CONTENT_TEMPLATE = R"(<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
@ -57,30 +57,30 @@ namespace vcpkg::Export::Chocolatey
|
||||
<file src="@EXPORTED_ROOT_DIR@\tools\**" target="tools" />
|
||||
</files>
|
||||
</package>
|
||||
)";
|
||||
auto package_version = packages_version.find(binary_paragraph.spec.name());
|
||||
if (package_version == packages_version.end())
|
||||
{
|
||||
Checks::exit_with_message(VCPKG_LINE_INFO, "Cannot find desired package version.");
|
||||
}
|
||||
std::string nuspec_file_content =
|
||||
Strings::replace_all(CONTENT_TEMPLATE, "@PACKAGE_ID@", binary_paragraph.spec.name());
|
||||
nuspec_file_content =
|
||||
Strings::replace_all(std::move(nuspec_file_content), "@PACKAGE_VERSION@", package_version->second);
|
||||
nuspec_file_content = Strings::replace_all(
|
||||
std::move(nuspec_file_content), "@PACKAGE_MAINTAINER@", chocolatey_options.maybe_maintainer.value_or(""));
|
||||
nuspec_file_content = Strings::replace_all(
|
||||
std::move(nuspec_file_content), "@PACKAGE_DESCRIPTION@", Strings::join("\n", binary_paragraph.description));
|
||||
nuspec_file_content =
|
||||
Strings::replace_all(std::move(nuspec_file_content), "@EXPORTED_ROOT_DIR@", exported_root_dir);
|
||||
nuspec_file_content = Strings::replace_all(std::move(nuspec_file_content),
|
||||
"@PACKAGE_DEPENDENCIES@",
|
||||
create_nuspec_dependencies(binary_paragraph, packages_version));
|
||||
return nuspec_file_content;
|
||||
}
|
||||
|
||||
static std::string create_chocolatey_install_contents()
|
||||
{
|
||||
)";
|
||||
auto package_version = packages_version.find(binary_paragraph.spec.name());
|
||||
if (package_version == packages_version.end())
|
||||
{
|
||||
Checks::exit_with_message(VCPKG_LINE_INFO, "Cannot find desired package version.");
|
||||
}
|
||||
std::string nuspec_file_content =
|
||||
Strings::replace_all(CONTENT_TEMPLATE, "@PACKAGE_ID@", binary_paragraph.spec.name());
|
||||
nuspec_file_content =
|
||||
Strings::replace_all(std::move(nuspec_file_content), "@PACKAGE_VERSION@", package_version->second);
|
||||
nuspec_file_content = Strings::replace_all(
|
||||
std::move(nuspec_file_content), "@PACKAGE_MAINTAINER@", chocolatey_options.maybe_maintainer.value_or(""));
|
||||
nuspec_file_content = Strings::replace_all(
|
||||
std::move(nuspec_file_content), "@PACKAGE_DESCRIPTION@", Strings::join("\n", binary_paragraph.description));
|
||||
nuspec_file_content =
|
||||
Strings::replace_all(std::move(nuspec_file_content), "@EXPORTED_ROOT_DIR@", exported_root_dir);
|
||||
nuspec_file_content = Strings::replace_all(std::move(nuspec_file_content),
|
||||
"@PACKAGE_DEPENDENCIES@",
|
||||
create_nuspec_dependencies(binary_paragraph, packages_version));
|
||||
return nuspec_file_content;
|
||||
}
|
||||
|
||||
static std::string create_chocolatey_install_contents()
|
||||
{
|
||||
static constexpr auto CONTENT_TEMPLATE = R"###(
|
||||
$ErrorActionPreference = 'Stop';
|
||||
|
||||
@ -93,12 +93,12 @@ $whereToInstall = (pwd).path
|
||||
$whereToInstallCache = Join-Path $rootDir 'install.txt'
|
||||
Set-Content -Path $whereToInstallCache -Value $whereToInstall
|
||||
Copy-Item $installedDir -destination $whereToInstall -recurse -force
|
||||
)###";
|
||||
return CONTENT_TEMPLATE;
|
||||
}
|
||||
|
||||
static std::string create_chocolatey_uninstall_contents(const BinaryParagraph& binary_paragraph)
|
||||
{
|
||||
)###";
|
||||
return CONTENT_TEMPLATE;
|
||||
}
|
||||
|
||||
static std::string create_chocolatey_uninstall_contents(const BinaryParagraph& binary_paragraph)
|
||||
{
|
||||
static constexpr auto CONTENT_TEMPLATE = R"###(
|
||||
$ErrorActionPreference = 'Stop';
|
||||
|
||||
@ -143,90 +143,90 @@ if (Test-Path $installedDir)
|
||||
}
|
||||
) { $empties | Remove-Item }
|
||||
}
|
||||
)###";
|
||||
std::string chocolatey_uninstall_content =
|
||||
Strings::replace_all(CONTENT_TEMPLATE, "@PACKAGE_FULLSTEM@", binary_paragraph.fullstem());
|
||||
return chocolatey_uninstall_content;
|
||||
}
|
||||
|
||||
void do_export(const std::vector<ExportPlanAction>& export_plan,
|
||||
const VcpkgPaths& paths,
|
||||
const Options& chocolatey_options)
|
||||
{
|
||||
Checks::check_exit(
|
||||
VCPKG_LINE_INFO, chocolatey_options.maybe_maintainer.has_value(), "--x-maintainer option is required.");
|
||||
|
||||
Files::Filesystem& fs = paths.get_filesystem();
|
||||
const fs::path vcpkg_root_path = paths.root;
|
||||
const fs::path raw_exported_dir_path = vcpkg_root_path / "chocolatey";
|
||||
const fs::path exported_dir_path = vcpkg_root_path / "chocolatey_exports";
|
||||
const fs::path& nuget_exe = paths.get_tool_exe(Tools::NUGET);
|
||||
|
||||
std::error_code ec;
|
||||
fs.remove_all(raw_exported_dir_path, VCPKG_LINE_INFO);
|
||||
fs.create_directory(raw_exported_dir_path, ec);
|
||||
fs.remove_all(exported_dir_path, VCPKG_LINE_INFO);
|
||||
fs.create_directory(exported_dir_path, ec);
|
||||
|
||||
// execute the plan
|
||||
std::map<std::string, std::string> packages_version;
|
||||
for (const ExportPlanAction& action : export_plan)
|
||||
{
|
||||
if (action.plan_type != ExportPlanType::ALREADY_BUILT)
|
||||
{
|
||||
Checks::unreachable(VCPKG_LINE_INFO);
|
||||
}
|
||||
|
||||
const BinaryParagraph& binary_paragraph = action.core_paragraph().value_or_exit(VCPKG_LINE_INFO);
|
||||
auto norm_version = binary_paragraph.version;
|
||||
|
||||
// normalize the version string to be separated by dots to be compliant with Nusepc.
|
||||
norm_version = Strings::replace_all(std::move(norm_version), "-", ".");
|
||||
norm_version = Strings::replace_all(std::move(norm_version), "_", ".");
|
||||
norm_version = norm_version + chocolatey_options.maybe_version_suffix.value_or("");
|
||||
packages_version.insert(std::make_pair(binary_paragraph.spec.name(), norm_version));
|
||||
}
|
||||
|
||||
for (const ExportPlanAction& action : export_plan)
|
||||
{
|
||||
const std::string display_name = action.spec.to_string();
|
||||
System::print2("Exporting package ", display_name, "...\n");
|
||||
|
||||
const fs::path per_package_dir_path = raw_exported_dir_path / action.spec.name();
|
||||
|
||||
const BinaryParagraph& binary_paragraph = action.core_paragraph().value_or_exit(VCPKG_LINE_INFO);
|
||||
|
||||
const InstallDir dirs = InstallDir::from_destination_root(
|
||||
per_package_dir_path / "installed",
|
||||
action.spec.triplet().to_string(),
|
||||
per_package_dir_path / "installed" / "vcpkg" / "info" / (binary_paragraph.fullstem() + ".list"));
|
||||
|
||||
Install::install_package_and_write_listfile(paths, action.spec, dirs);
|
||||
|
||||
const std::string nuspec_file_content = create_nuspec_file_contents(
|
||||
per_package_dir_path.string(), binary_paragraph, packages_version, chocolatey_options);
|
||||
const fs::path nuspec_file_path =
|
||||
per_package_dir_path / Strings::concat(binary_paragraph.spec.name(), ".nuspec");
|
||||
fs.write_contents(nuspec_file_path, nuspec_file_content, VCPKG_LINE_INFO);
|
||||
|
||||
fs.create_directory(per_package_dir_path / "tools", ec);
|
||||
|
||||
const std::string chocolatey_install_content = create_chocolatey_install_contents();
|
||||
const fs::path chocolatey_install_file_path = per_package_dir_path / "tools" / "chocolateyInstall.ps1";
|
||||
fs.write_contents(chocolatey_install_file_path, chocolatey_install_content, VCPKG_LINE_INFO);
|
||||
|
||||
const std::string chocolatey_uninstall_content = create_chocolatey_uninstall_contents(binary_paragraph);
|
||||
const fs::path chocolatey_uninstall_file_path = per_package_dir_path / "tools" / "chocolateyUninstall.ps1";
|
||||
fs.write_contents(chocolatey_uninstall_file_path, chocolatey_uninstall_content, VCPKG_LINE_INFO);
|
||||
|
||||
const auto cmd_line = Strings::format(R"("%s" pack -OutputDirectory "%s" "%s" -NoDefaultExcludes)",
|
||||
nuget_exe.u8string(),
|
||||
exported_dir_path.u8string(),
|
||||
nuspec_file_path.u8string());
|
||||
|
||||
const int exit_code =
|
||||
System::cmd_execute_and_capture_output(cmd_line, System::get_clean_environment()).exit_code;
|
||||
Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: NuGet package creation failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
)###";
|
||||
std::string chocolatey_uninstall_content =
|
||||
Strings::replace_all(CONTENT_TEMPLATE, "@PACKAGE_FULLSTEM@", binary_paragraph.fullstem());
|
||||
return chocolatey_uninstall_content;
|
||||
}
|
||||
|
||||
void do_export(const std::vector<ExportPlanAction>& export_plan,
|
||||
const VcpkgPaths& paths,
|
||||
const Options& chocolatey_options)
|
||||
{
|
||||
Checks::check_exit(
|
||||
VCPKG_LINE_INFO, chocolatey_options.maybe_maintainer.has_value(), "--x-maintainer option is required.");
|
||||
|
||||
Files::Filesystem& fs = paths.get_filesystem();
|
||||
const fs::path vcpkg_root_path = paths.root;
|
||||
const fs::path raw_exported_dir_path = vcpkg_root_path / "chocolatey";
|
||||
const fs::path exported_dir_path = vcpkg_root_path / "chocolatey_exports";
|
||||
const fs::path& nuget_exe = paths.get_tool_exe(Tools::NUGET);
|
||||
|
||||
std::error_code ec;
|
||||
fs.remove_all(raw_exported_dir_path, VCPKG_LINE_INFO);
|
||||
fs.create_directory(raw_exported_dir_path, ec);
|
||||
fs.remove_all(exported_dir_path, VCPKG_LINE_INFO);
|
||||
fs.create_directory(exported_dir_path, ec);
|
||||
|
||||
// execute the plan
|
||||
std::map<std::string, std::string> packages_version;
|
||||
for (const ExportPlanAction& action : export_plan)
|
||||
{
|
||||
if (action.plan_type != ExportPlanType::ALREADY_BUILT)
|
||||
{
|
||||
Checks::unreachable(VCPKG_LINE_INFO);
|
||||
}
|
||||
|
||||
const BinaryParagraph& binary_paragraph = action.core_paragraph().value_or_exit(VCPKG_LINE_INFO);
|
||||
auto norm_version = binary_paragraph.version;
|
||||
|
||||
// normalize the version string to be separated by dots to be compliant with Nusepc.
|
||||
norm_version = Strings::replace_all(std::move(norm_version), "-", ".");
|
||||
norm_version = Strings::replace_all(std::move(norm_version), "_", ".");
|
||||
norm_version = norm_version + chocolatey_options.maybe_version_suffix.value_or("");
|
||||
packages_version.insert(std::make_pair(binary_paragraph.spec.name(), norm_version));
|
||||
}
|
||||
|
||||
for (const ExportPlanAction& action : export_plan)
|
||||
{
|
||||
const std::string display_name = action.spec.to_string();
|
||||
System::print2("Exporting package ", display_name, "...\n");
|
||||
|
||||
const fs::path per_package_dir_path = raw_exported_dir_path / action.spec.name();
|
||||
|
||||
const BinaryParagraph& binary_paragraph = action.core_paragraph().value_or_exit(VCPKG_LINE_INFO);
|
||||
|
||||
const InstallDir dirs = InstallDir::from_destination_root(
|
||||
per_package_dir_path / "installed",
|
||||
action.spec.triplet().to_string(),
|
||||
per_package_dir_path / "installed" / "vcpkg" / "info" / (binary_paragraph.fullstem() + ".list"));
|
||||
|
||||
Install::install_package_and_write_listfile(paths, action.spec, dirs);
|
||||
|
||||
const std::string nuspec_file_content = create_nuspec_file_contents(
|
||||
per_package_dir_path.string(), binary_paragraph, packages_version, chocolatey_options);
|
||||
const fs::path nuspec_file_path =
|
||||
per_package_dir_path / Strings::concat(binary_paragraph.spec.name(), ".nuspec");
|
||||
fs.write_contents(nuspec_file_path, nuspec_file_content, VCPKG_LINE_INFO);
|
||||
|
||||
fs.create_directory(per_package_dir_path / "tools", ec);
|
||||
|
||||
const std::string chocolatey_install_content = create_chocolatey_install_contents();
|
||||
const fs::path chocolatey_install_file_path = per_package_dir_path / "tools" / "chocolateyInstall.ps1";
|
||||
fs.write_contents(chocolatey_install_file_path, chocolatey_install_content, VCPKG_LINE_INFO);
|
||||
|
||||
const std::string chocolatey_uninstall_content = create_chocolatey_uninstall_contents(binary_paragraph);
|
||||
const fs::path chocolatey_uninstall_file_path = per_package_dir_path / "tools" / "chocolateyUninstall.ps1";
|
||||
fs.write_contents(chocolatey_uninstall_file_path, chocolatey_uninstall_content, VCPKG_LINE_INFO);
|
||||
|
||||
const auto cmd_line = Strings::format(R"("%s" pack -OutputDirectory "%s" "%s" -NoDefaultExcludes)",
|
||||
nuget_exe.u8string(),
|
||||
exported_dir_path.u8string(),
|
||||
nuspec_file_path.u8string());
|
||||
|
||||
const int exit_code =
|
||||
System::cmd_execute_and_capture_output(cmd_line, System::get_clean_environment()).exit_code;
|
||||
Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: NuGet package creation failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user