From 812f12aaa1a98418514ca58cd9360539c5e88a08 Mon Sep 17 00:00:00 2001 From: Firefly35 Date: Tue, 2 Mar 2021 11:00:29 +0100 Subject: [PATCH 1/3] fix[github ssl issue]: replace beast http download with curl - ssl protocol finalization has some issues using beast (handling errors correctly doesn't address the ssl layer close latency issue) --- packagedependencies.txt | 2 +- remaken.pro | 2 +- src/Constants.h | 2 +- src/Dependency.cpp | 4 +++- src/HttpFileRetriever.cpp | 24 ++++++++++++++++++++++++ 5 files changed, 30 insertions(+), 4 deletions(-) mode change 100644 => 100755 src/Constants.h mode change 100644 => 100755 src/HttpFileRetriever.cpp diff --git a/packagedependencies.txt b/packagedependencies.txt index 7a6cd52..c20b0ee 100644 --- a/packagedependencies.txt +++ b/packagedependencies.txt @@ -1,2 +1,2 @@ -boost|1.71.0|boost|conan|conan-center|default|zlib=False#bzip2=False +boost|1.74.0|boost|conan|conan-center|default|zlib=False#bzip2=False openssl|1.1.1f|openssl|conan|conan-center diff --git a/remaken.pro b/remaken.pro index b6bc7b4..1c3c07d 100755 --- a/remaken.pro +++ b/remaken.pro @@ -1,5 +1,5 @@ TARGET = remaken -VERSION=1.7.1 +VERSION=1.7.2 CONFIG += c++1z CONFIG += console diff --git a/src/Constants.h b/src/Constants.h old mode 100644 new mode 100755 index 753074c..a7ca623 --- a/src/Constants.h +++ b/src/Constants.h @@ -35,7 +35,7 @@ class Constants { static constexpr const char * REMAKEN_PROFILES_FOLDER = "profiles"; static constexpr const char * REMAKEN_CACHE_FILE = ".remaken-cache"; static constexpr const char * ARTIFACTORY_API_KEY = "artifactoryApiKey"; - static constexpr const char * QMAKE_RULES_DEFAULT_TAG = "4.6.1"; + static constexpr const char * QMAKE_RULES_DEFAULT_TAG = "4.6.3"; }; #include diff --git a/src/Dependency.cpp b/src/Dependency.cpp index 7299e3d..67225d5 100755 --- a/src/Dependency.cpp +++ b/src/Dependency.cpp @@ -124,8 +124,10 @@ Dependency::Dependency(const std::string & rawFormat, const std::string & mainMo }*/ } if (results.size() == 7){ - m_bHasOptions = true; m_toolOptions = stripEndlineChar(results[6]); + if (!m_toolOptions.empty()) { + m_bHasOptions = true; + } } } diff --git a/src/HttpFileRetriever.cpp b/src/HttpFileRetriever.cpp old mode 100644 new mode 100755 index 044ceaf..95d27ba --- a/src/HttpFileRetriever.cpp +++ b/src/HttpFileRetriever.cpp @@ -8,7 +8,9 @@ #include #include #include "HttpHandlerFactory.h" +#include +namespace bp = boost::process; using tcp = boost::asio::ip::tcp; // from namespace http = boost::beast::http; @@ -97,6 +99,8 @@ inline HttpStatus convertStatus(const http::status & status) return httpStatusConverter.at(status); } +#ifdef REMAKEN_USE_BEAST + fs::path HttpFileRetriever::retrieveArtefact(const std::string & source) { // LOGGER.info(std::string.format("Download file %s", url)); @@ -123,6 +127,26 @@ fs::path HttpFileRetriever::retrieveArtefact(const std::string & source) return output; } +#else + +fs::path HttpFileRetriever::retrieveArtefact(const std::string & source) +{ + // LOGGER.info(std::string.format("Download file %s", url)); + boost::uuids::uuid uuid = boost::uuids::random_generator()(); + fs::path output = this->m_workingDirectory / boost::uuids::to_string(uuid); + //cpr::Response r = cpr::Get(cpr::Url{source}); + boost::filesystem::path tool = bp::search_path("curl"); + if (!tool.empty()) { + int result = bp::system(tool, "-L", "-f", source, "-o", output); + if (result != 0) { + std::cout << source<(result))); + } + } + return output; +} +#endif + fs::path HttpFileRetriever::retrieveArtefact(const Dependency & dependency) { // LOGGER.info(std::string.format("Download file %s", url)); From 88845e22925d412b31075fc979f63bab82fe6aac Mon Sep 17 00:00:00 2001 From: Firefly35 Date: Tue, 2 Mar 2021 12:31:15 +0100 Subject: [PATCH 2/3] fix[issue #7]: Inconsistency in CLI parser for linux support fix[issue #8]: Misleading error message for unknown dependency: "Unknown repository type" fix[issue #10]: Handling of trailing pipe for empty options of conan dependencies with remaken bundle fix[github-ssl-beast]: handle shutdown protocol weird behavior for beast feat[comment]: ignore commented lines from packagedependencies*.txt (commented line starts with // ) feat[info command]: add package information command : lists the dependency graph of an installed package from its packagedependencies file. feat[force]: add force option to force installation, rules initialization (allows to force reinstallation of rules) - use it with override flag to silently replace every file --- remaken.pro | 7 ++- src/AsioWrapper.h | 15 ++++- src/CmdOptions.cpp | 76 +++++++++++++++---------- src/CmdOptions.h | 15 +++-- src/Dependency.cpp | 3 + src/DependencyManager.cpp | 111 +++++++++++++++++++++++++++++++------ src/DependencyManager.h | 7 ++- src/FileHandlerFactory.cpp | 3 + src/HttpFileRetriever.cpp | 3 + src/InfoCommand.cpp | 12 ++++ src/InfoCommand.h | 39 +++++++++++++ src/InitCommand.cpp | 7 ++- src/ProfileCommand.cpp | 2 +- src/main.cpp | 4 +- 14 files changed, 246 insertions(+), 58 deletions(-) mode change 100644 => 100755 src/CmdOptions.cpp create mode 100755 src/InfoCommand.cpp create mode 100644 src/InfoCommand.h diff --git a/remaken.pro b/remaken.pro index 1c3c07d..8188cd0 100755 --- a/remaken.pro +++ b/remaken.pro @@ -40,6 +40,7 @@ HEADERS += \ src/Constants.h \ src/Cache.h \ src/AbstractCommand.h \ + src/InfoCommand.h \ src/InitCommand.h \ src/InstallCommand.h \ src/PathBuilder.h \ @@ -67,6 +68,7 @@ HEADERS += \ SOURCES += \ src/BundleXpcfCommand.cpp \ src/CleanCommand.cpp \ + src/InfoCommand.cpp \ src/InitCommand.cpp \ src/PathBuilder.cpp \ src/ProfileCommand.cpp \ @@ -108,11 +110,14 @@ linux { } macx { + DEFINES += _MACOS_TARGET_ QMAKE_MAC_SDK= macosx + QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.15 QMAKE_CXXFLAGS += -fasm-blocks -x objective-c++ -std=c++17 #LIBS += -L/usr/lib -lz -lssl -lcrypto -L/usr/local/lib -lZipper-static #Zipper dependency : https://github.com/sebastiandev/zipper - LIBS += -L/usr/local/lib -lz -lZipper-static -lboost_system + LIBS += -L/usr/local/lib -lboost_system -lstdc++ + QMAKE_LFLAGS += -mmacosx-version-min=10.15 -v -lstdc++ INCLUDEPATH += /usr/local/include } diff --git a/src/AsioWrapper.h b/src/AsioWrapper.h index 348ec12..c09cc8e 100644 --- a/src/AsioWrapper.h +++ b/src/AsioWrapper.h @@ -246,11 +246,24 @@ void AsioStreamWrapper::shutdown() { boost::system::error_code ec; m_comLayer.shutdown(ec); + int reason = ERR_GET_REASON(ec.value()); + if (((ec.category() == boost::asio::error::get_ssl_category()) || (ec.category() == boost::asio::ssl::error::get_stream_category())) + && (reason == ssl::error::stream_truncated)) + { + // Remote peer failed to send a close_notify message. + ec = {}; +// m_comLayer.lowest_layer().close(); + } + + if(ec == boost::asio::error::operation_aborted) + { + ec = {}; + } if(ec == boost::asio::error::eof) { // Rationale: // http://stackoverflow.com/questions/25587403/boost-asio-ssl-async-shutdown-always-finishes-with-an-error - ec.assign(0, ec.category()); + ec = {}; } if(ec) throw boost::system::system_error{ec}; diff --git a/src/CmdOptions.cpp b/src/CmdOptions.cpp old mode 100644 new mode 100755 index 2ebdb3f..109f259 --- a/src/CmdOptions.cpp +++ b/src/CmdOptions.cpp @@ -56,6 +56,31 @@ std::string computeToolChain() } +static const map> validationMap ={{"action",{"info","init","install","parse","version","bundle","bundleXpcf"}}, + {"--architecture",{"x86_64","i386","arm","arm64","arm64-v8a","armeabi-v7a","armv6","armv7","armv7hf","armv8"}}, + {"--config",{"release","debug"}}, + {"--mode",{"shared","static"}}, + {"--type",{"github","artifactory","nexus","path"}}, + {"--alternate-remote-type",{"github","artifactory","nexus","path"}}, + {"--operating-system",{"mac","win","unix","android","ios","linux"}}, + {"--cpp-std",{"11","14","17","20"}} + }; + + +std::string CmdOptions::getOptionString(const std::string & optionName) +{ + std::string out = ""; + if ( mapContains(validationMap,optionName) ) { + for ( auto & value: validationMap.at(optionName) ) { + if (!out.empty()) { + out += ", "; + } + out += value; + } + } + return out; +} + CmdOptions::CmdOptions() { fs::detail::utf8_codecvt_facet utf8; @@ -87,20 +112,23 @@ CmdOptions::CmdOptions() m_cliApp.set_config("--configfile",configPath.generic_string(utf8),"remaken configuration file to read"); m_config = "release"; - m_cliApp.add_option("--config,-c", m_config, "Config: release, debug", true); + m_cliApp.add_option("--config,-c", m_config, "Config: " + getOptionString("--config"), true); m_cppVersion = "11"; - m_cliApp.add_option("--cpp-std",m_cppVersion, "c++ standard version: 11, 14, 17, 20 ...", true); + m_cliApp.add_option("--cpp-std",m_cppVersion, "c++ standard version: " + getOptionString("--cpp-std"), true); m_remakenRoot = remakenRootPath.generic_string(utf8); m_cliApp.add_option("--remaken-root,-r", m_remakenRoot, "Remaken root directory", true); m_toolchain = computeToolChain(); m_cliApp.add_option("--build-toolchain,-b", m_toolchain, "Build toolchain: clang, clang-version, " "gcc-version, cl-version .. ex: cl-14.1", true); m_os = computeOS(); - m_cliApp.add_option("--operating-system,-o", m_os, "Operating system: mac, win, unix, ios, android", true); + m_cliApp.add_option("--operating-system,-o", m_os, "Operating system: " + getOptionString("--operating-system"), true); m_architecture = "x86_64"; - m_cliApp.add_option("--architecture,-a",m_architecture, "Architecture: x86_64, i386, arm, arm64, arm64-v8a, armeabi-v7a, armv6, armv7, armv7hf, armv8",true); + m_cliApp.add_option("--architecture,-a",m_architecture, "Architecture: " + getOptionString("--architecture"),true); + m_cliApp.add_flag("--force,-f", m_force, "force command execution : ignore cache entries, already installed files ..."); m_verbose = false; m_cliApp.add_flag("--verbose,-v", m_verbose, "verbose mode"); + m_override = false; + m_cliApp.add_flag("--override,-e", m_override, "override existing files while (re)-installing packages/rules..."); m_dependenciesFile = "packagedependencies.txt"; CLI::App * bundleCommand = m_cliApp.add_subcommand("bundle","copy shared libraries dependencies to a destination folder"); @@ -114,35 +142,38 @@ CmdOptions::CmdOptions() "copied with their dependencies", true); bundleXpcfCommand->add_option("file", m_dependenciesFile, "XPCF xml module declaration file")->required(); - CLI::App * cleanCommand = m_cliApp.add_subcommand("clean","WARNING : remove every remaken installed packages"); + CLI::App * cleanCommand = m_cliApp.add_subcommand("clean", "WARNING : remove every remaken installed packages"); + + CLI::App * infoCommand = m_cliApp.add_subcommand("info", "Read package dependencies informations"); + infoCommand->add_option("file", m_dependenciesFile, "Remaken dependencies files", true); - CLI::App * profileCommand = m_cliApp.add_subcommand("profile","manage remaken profiles configuration"); - CLI::App * initProfileCommand = profileCommand->add_subcommand("init","create remaken default profile from current options"); - CLI::App * displayProfileCommand = profileCommand->add_subcommand("display","display remaken current profile (display current options and profile options)"); + + CLI::App * profileCommand = m_cliApp.add_subcommand("profile", "manage remaken profiles configuration"); + CLI::App * initProfileCommand = profileCommand->add_subcommand("init", "create remaken default profile from current options"); + CLI::App * displayProfileCommand = profileCommand->add_subcommand("display", "display remaken current profile (display current options and profile options)"); m_defaultProfileOptions = false; displayProfileCommand->add_flag("--with-default,-w", m_defaultProfileOptions, "display all profile options : default and provided"); initProfileCommand ->add_flag("--with-default,-w", m_defaultProfileOptions, "create remaken profile with all profile options : default and provided"); - CLI::App * initCommand = m_cliApp.add_subcommand("init","initialize remaken root folder and retrieve qmake rules"); + CLI::App * initCommand = m_cliApp.add_subcommand("init", "initialize remaken root folder and retrieve qmake rules"); m_qmakeRulesTag = Constants::QMAKE_RULES_DEFAULT_TAG; initCommand->add_option("--tag", m_qmakeRulesTag, "the qmake rules tag version to install - either provide a tag or the keyword 'latest' to install latest qmake rules",true); - CLI::App * versionCommand = m_cliApp.add_subcommand("version","display remaken version"); + CLI::App * versionCommand = m_cliApp.add_subcommand("version", "display remaken version"); - CLI::App * installCommand = m_cliApp.add_subcommand("install","install dependencies for a package from its packagedependencies file(s)"); - installCommand->add_option("--alternate-remote-type,-l", m_altRepoType, "alternate remote type: github, artifactory, nexus, path"); + CLI::App * installCommand = m_cliApp.add_subcommand("install", "install dependencies for a package from its packagedependencies file(s)"); + installCommand->add_option("--alternate-remote-type,-l", m_altRepoType, "alternate remote type: " + getOptionString("--alternate-remote-type")); installCommand->add_option("--alternate-remote-url,-u", m_altRepoUrl, "alternate remote url to use when the declared remote fails to provide a dependency"); installCommand->add_option("--apiKey,-k", m_apiKey, "Artifactory api key"); - m_override = false; - installCommand->add_flag("--override,-e", m_override, "override existing files while (re)-installing packages"); + installCommand->add_option("file", m_dependenciesFile, "Remaken dependencies files", true); m_ignoreCache = false; installCommand->add_flag("--ignore-cache,-i", m_ignoreCache, "ignore cache entries : dependencies update is forced"); m_mode = "shared"; - installCommand->add_option("--mode,-m", m_mode, "Mode: shared, static", true); + installCommand->add_option("--mode,-m", m_mode, "Mode: " + getOptionString("--mode"), true); m_repositoryType = "github"; - installCommand->add_option("--type,-t", m_repositoryType, "Repository type: github, artifactory, nexus, path", true); + installCommand->add_option("--type,-t", m_repositoryType, "Repository type: " + getOptionString("--type"), true); m_zipTool = ZipTool::getZipToolIdentifier(); installCommand->add_option("--ziptool,-z", m_zipTool, "unzipper tool name : unzip, compact ...", true); @@ -150,17 +181,6 @@ CmdOptions::CmdOptions() parseCommand->add_option("file", m_dependenciesFile, "Remaken dependencies files", true); } - -static const map> validationMap ={{"action",{"install","parse","version","bundle", "bundleXpcf"}}, - {"--architecture",{"x86_64","i386","arm","arm64","arm64-v8a","armeabi-v7a","armv6","armv7","armv7hf","armv8"}}, - {"--config",{"release","debug"}}, - {"--mode",{"shared","static"}}, - {"--type",{"github","artifactory","nexus","path"}}, - {"--alternate-remote-type",{"github","artifactory","nexus","path"}}, - {"--operating-system",{"mac","win","unix","android","ios","linux"}}, - {"--cpp-std",{"11","14","17","20"}} - }; - void CmdOptions::initBuildConfig() { m_buildConfig = getOS(); @@ -213,7 +233,7 @@ CmdOptions::OptionResult CmdOptions::parseArguments(int argc, char** argv) validateOptions(); auto sub = m_cliApp.get_subcommands().at(0); if (sub->get_name() == "profile") { - m_profileSubcommand = sub->get_subcommands().at(0)->get_name(); + m_subcommand = sub->get_subcommands().at(0)->get_name(); } if (m_cliApp.get_subcommands().size() == 1) { m_action = m_cliApp.get_subcommands().at(0)->get_name(); diff --git a/src/CmdOptions.h b/src/CmdOptions.h index 63be683..a13f60f 100755 --- a/src/CmdOptions.h +++ b/src/CmdOptions.h @@ -133,13 +133,16 @@ class CmdOptions return m_override; } + bool force() const { + return m_force; + } + const std::string & getBuildConfig() const { return m_buildConfig; } - - - const std::string & getProfileSubcommand() const { - return m_profileSubcommand; + + const std::string & getSubcommand() const { + return m_subcommand; } const std::string & getQmakeRulesTag() const { @@ -150,6 +153,7 @@ class CmdOptions void displayConfigurationSettings() const; private: + std::string getOptionString(const std::string & optionName); void validateOptions(); void initBuildConfig(); std::string m_action; @@ -171,13 +175,14 @@ class CmdOptions std::string m_altRepoType; std::string m_moduleSubfolder; std::string m_buildConfig; - std::string m_profileSubcommand; + std::string m_subcommand; std::string m_qmakeRulesTag; fs::path m_moduleSubfolderPath; bool m_ignoreCache; bool m_verbose; bool m_isXpcfBundle = false; bool m_cleanAll = true; + bool m_force = false; bool m_override = false; bool m_defaultProfileOptions = false; CLI::App m_cliApp{"remaken"}; diff --git a/src/Dependency.cpp b/src/Dependency.cpp index 67225d5..aa3d1ce 100755 --- a/src/Dependency.cpp +++ b/src/Dependency.cpp @@ -116,6 +116,9 @@ Dependency::Dependency(const std::string & rawFormat, const std::string & mainMo if (results.size() >= 6){ m_mode = stripEndlineChar(results[5]); boost::trim(m_mode); + if (m_mode!= "static" && m_mode!= "shared" && m_mode!= "na") { + m_mode = mainMode; + } } else { m_mode = mainMode; diff --git a/src/DependencyManager.cpp b/src/DependencyManager.cpp index 83131b5..2090a6f 100755 --- a/src/DependencyManager.cpp +++ b/src/DependencyManager.cpp @@ -44,7 +44,7 @@ DependencyManager::DependencyManager(const CmdOptions & options):m_options(optio fs::path DependencyManager::buildDependencyPath() { fs::detail::utf8_codecvt_facet utf8; - fs::path currentPath(fs::current_path().generic_string(utf8)); + fs::path currentPath(boost::filesystem::initial_path().generic_string(utf8)); fs::path dependenciesFile (m_options.getDependenciesFile(),utf8); @@ -75,7 +75,7 @@ int DependencyManager::parse() bool bValid = true; bool bNeedElevation = false; fs::path depPath = buildDependencyPath(); - std::vector dependencies = parse(depPath); + std::vector dependencies = parse(depPath, m_options.getMode()); for (auto dep : dependencies) { if (!dep.validate()) { bValid = false; @@ -148,6 +148,61 @@ int DependencyManager::clean() return 0; } +const std::string indentStr = " "; + +std::string indent(uint32_t indentLevel) { + std::string ind; + for (uint32_t i = 0; i dependenciesFileList = getChildrenDependencies(dependenciesFile.parent_path(), m_options.getOS()); + for (fs::path depsFile : dependenciesFileList) { + if (fs::exists(depsFile)) { + std::vector dependencies = parse(depsFile, m_options.getMode()); + for (auto dep : dependencies) { + if (!dep.validate()) { + throw std::runtime_error("Error parsing dependency file : invalid format "); + m_indentLevel --; + } + } + for (Dependency & dependency : dependencies) { + displayInfo(dependency, m_indentLevel); + fs::detail::utf8_codecvt_facet utf8; + shared_ptr fileRetriever = FileHandlerFactory::instance()->getFileHandler(dependency, m_options); + fs::path outputDirectory = fileRetriever->computeLocalDependencyRootDir(dependency); + readInfos(outputDirectory/"packagedependencies.txt"); + } + } + } + m_indentLevel --; +} + + +int DependencyManager::info() +{ + try { + fs::path dependencyPath = buildDependencyPath(); + readInfos(dependencyPath); + } + catch (const std::runtime_error & e) { + BOOST_LOG_TRIVIAL(error)< fileRetriever = FileHandlerFactory::instance()->getFileHandler(dependency, m_options); fs::path outputDirectory = fileRetriever->bundleArtefact(dependency); if (!outputDirectory.empty() && dependency.getType() == Dependency::Type::REMAKEN) { - std::vector childrenDependencies = getChildrenDependencies(outputDirectory); + std::vector childrenDependencies = getChildrenDependencies(outputDirectory, m_options.getOS()); for (fs::path childDependency : childrenDependencies) { if (fs::exists(childDependency)) { this->bundleDependencies(childDependency); @@ -321,7 +376,7 @@ void DependencyManager::bundleDependency(const Dependency & dependency) void DependencyManager::bundleDependencies(const fs::path & dependenciesFile) { if (fs::exists(dependenciesFile)){ - std::vector dependencies = parse(dependenciesFile); + std::vector dependencies = parse(dependenciesFile, m_options.getMode()); for (auto dependency : dependencies) { if (dependency.getType() == Dependency::Type::REMAKEN) { if (!dependency.validate()) { @@ -374,7 +429,7 @@ std::vector removeRedundantDependencies(const std::multimap DependencyManager::parse(const fs::path & dependenciesPath) +std::vector DependencyManager::parse(const fs::path & dependenciesPath, const std::string & linkMode) { std::multimap libraries; if (fs::exists(dependenciesPath)) { @@ -383,10 +438,20 @@ std::vector DependencyManager::parse(const fs::path & dependenciesP string curStr; getline(fis,curStr); if (!curStr.empty()) { - Dependency dep(curStr, m_options.getMode()); - if (isGenericSystemDependency(dep)||isSpecificSystemToolDependency(dep)||!isSystemDependency(dep)) { - // only add "generic" system or tool@system or other deps - libraries.insert(std::make_pair(dep.getName(), std::move(dep))); + std::string commentRegexStr = "^[ \t]*//"; + std::regex commentRegex(commentRegexStr, std::regex_constants::extended); + std::smatch sm; + // parsing finds commented lines + if (!std::regex_search(curStr, sm, commentRegex, std::regex_constants::match_any)) { + // Dependency line is not commented: parsing the dependency + Dependency dep(curStr, linkMode); + if (isGenericSystemDependency(dep)||isSpecificSystemToolDependency(dep)||!isSystemDependency(dep)) { + // only add "generic" system or tool@system or other deps + libraries.insert(std::make_pair(dep.getName(), std::move(dep))); + } + } + else { + std::cout<<"[IGNORED]: Dependency line '"<computeSourcePath(dependency); fs::path outputDirectory = fileRetriever->computeLocalDependencyRootDir(dependency); fs::path libDirectory = fileRetriever->computeRootLibDir(dependency); - if (installDep(dependency, source, outputDirectory, libDirectory)) { + if (installDep(dependency, source, outputDirectory, libDirectory) || m_options.force()) { try { std::cout<<"=> Installing "< fileRetriever = FileHandlerFactory::instance()->getFileHandler(m_options,true); - dependency.changeBaseRepository(m_options.getAlternateRepoUrl()); - source = fileRetriever->computeSourcePath(dependency); - outputDirectory = fileRetriever->installArtefact(dependency); + if (!fileRetriever) { // no alternate repository found + BOOST_LOG_TRIVIAL(error)<<"Unable to find '"<computeSourcePath(dependency); + try { + outputDirectory = fileRetriever->installArtefact(dependency); + } + catch (std::runtime_error & e) { + BOOST_LOG_TRIVIAL(error)<<"Unable to find '"< "< dependenciesFileList = getChildrenDependencies(dependenciesFile.parent_path()); + std::vector dependenciesFileList = getChildrenDependencies(dependenciesFile.parent_path(), m_options.getOS()); for (fs::path depsFile : dependenciesFileList) { if (fs::exists(depsFile)) { - std::vector dependencies = parse(depsFile); + std::vector dependencies = parse(depsFile, m_options.getMode()); for (auto dep : dependencies) { if (!dep.validate()) { throw std::runtime_error("Error parsing dependency file : invalid format "); @@ -510,10 +587,10 @@ void DependencyManager::retrieveDependencies(const fs::path & dependenciesFile) } } -std::vector DependencyManager::getChildrenDependencies(const fs::path & outputDirectory) +std::vector DependencyManager::getChildrenDependencies(const fs::path & outputDirectory, const std::string & osPlatform) { auto childrenDependencies = list{"packagedependencies.txt"}; - childrenDependencies.push_back("packagedependencies-"+ m_options.getOS() + ".txt"); + childrenDependencies.push_back("packagedependencies-"+ osPlatform + ".txt"); std::vector subDepsPath; for (std::string childDependency : childrenDependencies) { fs::path chidrenPackageDependenciesPath = outputDirectory / childDependency; diff --git a/src/DependencyManager.h b/src/DependencyManager.h index 66ca915..2854db9 100755 --- a/src/DependencyManager.h +++ b/src/DependencyManager.h @@ -39,28 +39,31 @@ class DependencyManager public: DependencyManager(const CmdOptions & options); fs::path buildDependencyPath(); + int info(); int retrieve(); int parse(); int bundle(); int bundleXpcf(); int clean(); + static std::vector getChildrenDependencies(const fs::path & outputDirectory, const std::string & osPlatform); + static std::vector parse(const fs::path & dependenciesPath, const std::string & linkMode); private: void updateModuleNode(tinyxml2::XMLElement * xmlModuleElt); int updateXpcfModulesPath(const fs::path & configurationFilePath); void declareModule(tinyxml2::XMLElement * xmlModuleElt); int parseXpcfModulesConfiguration(const fs::path & configurationFilePath); - std::vector parse(const fs::path & dependenciesPath); void bundleDependencies(const fs::path & dependenciesFiles); void bundleDependency(const Dependency & dep); void retrieveDependencies(const fs::path & dependenciesFiles); void retrieveDependency(Dependency & dependency); - std::vector getChildrenDependencies(const fs::path & outputDirectory); bool installDep(Dependency & dependency, const std::string & source, const fs::path & outputDirectory, const fs::path & libDirectory); + void readInfos(const fs::path & dependenciesFile); std::map m_modulesPathMap; std::map m_modulesUUiDMap; const CmdOptions & m_options; + uint32_t m_indentLevel = 0; Cache m_cache; }; diff --git a/src/FileHandlerFactory.cpp b/src/FileHandlerFactory.cpp index 8c8ee17..323ea9e 100644 --- a/src/FileHandlerFactory.cpp +++ b/src/FileHandlerFactory.cpp @@ -31,6 +31,9 @@ std::shared_ptr FileHandlerFactory::getFileHandler(const CmdOpti std::string repoType = options.getRepositoryType(); if (useAlternateRepo) { repoType = options.getAlternateRepoType(); + if (repoType.empty()) { + return nullptr; + } } if (repoType == "github") { return make_shared(options); diff --git a/src/HttpFileRetriever.cpp b/src/HttpFileRetriever.cpp index 95d27ba..d3e653b 100755 --- a/src/HttpFileRetriever.cpp +++ b/src/HttpFileRetriever.cpp @@ -143,6 +143,9 @@ fs::path HttpFileRetriever::retrieveArtefact(const std::string & source) throw std::runtime_error("Bad http response : curl error code : " + std::to_string(static_cast(result))); } } + else { + throw std::runtime_error("Curl not installed : check your installation !!!"); + } return output; } #endif diff --git a/src/InfoCommand.cpp b/src/InfoCommand.cpp new file mode 100755 index 0000000..4459fb3 --- /dev/null +++ b/src/InfoCommand.cpp @@ -0,0 +1,12 @@ +#include "InfoCommand.h" +#include "DependencyManager.h" + +InfoCommand::InfoCommand(const CmdOptions & options):AbstractCommand(InfoCommand::NAME),m_options(options) +{ +} + +int InfoCommand::execute() +{ + auto mgr = DependencyManager{m_options}; + return mgr.info(); +} diff --git a/src/InfoCommand.h b/src/InfoCommand.h new file mode 100644 index 0000000..2a7098b --- /dev/null +++ b/src/InfoCommand.h @@ -0,0 +1,39 @@ +/** + * @copyright Copyright (c) 2019 B-com http://www.b-com.com/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @author Loïc Touraine + * + * @file + * @date 2021-02-24 + */ + +#ifndef INFOCOMMAND_H +#define INFOCOMMAND_H + +#include "AbstractCommand.h" +#include "CmdOptions.h" + +class InfoCommand : public AbstractCommand +{ +public: + InfoCommand(const CmdOptions & options); + int execute() override; + static constexpr const char * NAME="clean"; + +private: + const CmdOptions & m_options; +}; + +#endif diff --git a/src/InitCommand.cpp b/src/InitCommand.cpp index 523cb3c..4bd8025 100755 --- a/src/InitCommand.cpp +++ b/src/InitCommand.cpp @@ -44,7 +44,10 @@ int InitCommand::execute() if (!fs::exists(remakenProfilesPath)) { fs::create_directories(remakenProfilesPath); } - if (linkStatus.type() != fs::file_not_found || fs::exists(qmakeRootPath)) { + if (m_options.force()) { + fs::remove(qmakeRootPath); + } + else if (linkStatus.type() != fs::file_not_found || fs::exists(qmakeRootPath)) { BOOST_LOG_TRIVIAL(info)<<"qmake rules already installed ! skipping..."; return 0; } @@ -58,7 +61,7 @@ int InitCommand::execute() } source += release; source += "/builddefs-qmake-package.zip"; - BOOST_LOG_TRIVIAL(info)<<"Installing qmake rules version "< #include "Constants.h" #include "CmdOptions.h" +#include "InfoCommand.h" #include "InitCommand.h" #include "InstallCommand.h" #include "ParseCommand.h" @@ -24,13 +25,14 @@ int main(int argc, char** argv) } dispatcher["clean"] = make_shared(opts); dispatcher["init"] = make_shared(opts); + dispatcher["info"] = make_shared(opts); dispatcher["install"] = make_shared(opts); dispatcher["parse"] = make_shared(opts); dispatcher["bundle"] = make_shared(opts); dispatcher["bundleXpcf"] = make_shared(opts); dispatcher["profile"] = make_shared(opts); dispatcher["version"] = make_shared(); - if (mapContains(dispatcher,opts.getAction())) { + if (mapContains(dispatcher, opts.getAction())) { dispatcher.at(opts.getAction())->execute(); } else { From 8b8029db8fcfb133854ea05f03486252ec781b65 Mon Sep 17 00:00:00 2001 From: stefled Date: Tue, 2 Mar 2021 14:08:58 +0100 Subject: [PATCH 3/3] feat[nsis] : install curl during remaken setup on Windows --- resources/install_remaken_3rdparties.nsh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/resources/install_remaken_3rdparties.nsh b/resources/install_remaken_3rdparties.nsh index 9a17047..8b115d3 100644 --- a/resources/install_remaken_3rdparties.nsh +++ b/resources/install_remaken_3rdparties.nsh @@ -88,6 +88,13 @@ SectionGroup /e "Chocolatey" CHOCO_TOOLS ExecWait '$1\ProgramData\Chocolatey\choco install -yr --acceptlicense --no-progress 7zip' sevenz_exists: SectionEnd + + Section "Curl" CHOCO_TOOLS_CURL + IfFileExists "$1\ProgramData\chocolatey\bin\curl.exe" curl_exists + ExecWait '$1\ProgramData\Chocolatey\choco install -yr --acceptlicense --no-progress curl' + curl_exists: + SectionEnd + Section "Conan (with python/pip)" CONAN StrCpy $python_install_dir $1\Python37 ; default dir ReadRegStr $0 HKLM "SOFTWARE\Python\PythonCore\3.7\InstallPath" "" @@ -152,6 +159,7 @@ Function CustomizeOnInit SectionSetFlags ${REMAKEN_APP} 17 ; selected and ReadOnly SectionSetFlags ${CHOCO_TOOLS} 51 ; selected, ReadOnly and expanded SectionSetFlags ${CHOCO_TOOLS_7ZIP} 17 + SectionSetFlags ${CHOCO_TOOLS_CURL} 17 ; manage custom REMAKEN_PKG_ROOT SetRegView 64 @@ -175,6 +183,7 @@ FunctionEnd !insertmacro MUI_DESCRIPTION_TEXT ${REMAKEN_APP} "Install Remaken Tool" !insertmacro MUI_DESCRIPTION_TEXT ${CHOCO_TOOLS} "Remaken use Chocolatey as system install tool" !insertmacro MUI_DESCRIPTION_TEXT ${CHOCO_TOOLS_7ZIP} "Remaken use 7zip as system file compression/extraction tool" + !insertmacro MUI_DESCRIPTION_TEXT ${CHOCO_TOOLS_CURL} "Remaken use Curl as system file download tool" !insertmacro MUI_DESCRIPTION_TEXT ${CONAN} "Remaken can use Conan dependencies (Conan will be installed with Python and Pip also installed)" !insertmacro MUI_DESCRIPTION_TEXT ${CHOCO_TOOLS_PKG_CONFIG} "Remaken provides its own C++ packaging structure, based on pkg-config description files (pkg-config will be installed with Choco)" !insertmacro MUI_DESCRIPTION_TEXT ${CHOCO_TOOLS_CMAKE} "Conan can uses CMake for build packages (CMake will be installed with Choco)"