diff --git a/.gitignore b/.gitignore index 2ca936e..7bdc498 100644 --- a/.gitignore +++ b/.gitignore @@ -16,5 +16,3 @@ vgcore.* config.json *.txt actions-runner/ -**.tar.gz -**.tar.zst diff --git a/.gitmodules b/.gitmodules index 45d6005..1efeb8d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,6 +16,3 @@ [submodule "modules/argparse"] path = modules/argparse url = https://github.com/p-ranav/argparse -[submodule "modules/indicators"] - path = modules/indicators - url = https://github.com/p-ranav/indicators diff --git a/.trunk/.gitignore b/.trunk/.gitignore new file mode 100644 index 0000000..507283d --- /dev/null +++ b/.trunk/.gitignore @@ -0,0 +1,3 @@ +*out +*logs +external diff --git a/.trunk/actions b/.trunk/actions new file mode 120000 index 0000000..2dc78ea --- /dev/null +++ b/.trunk/actions @@ -0,0 +1 @@ +/home/david/.cache/trunk/repos/4c139ff7a07a0441c956056eef1736ac/actions \ No newline at end of file diff --git a/.trunk/notifications b/.trunk/notifications new file mode 120000 index 0000000..510975e --- /dev/null +++ b/.trunk/notifications @@ -0,0 +1 @@ +/home/david/.cache/trunk/repos/4c139ff7a07a0441c956056eef1736ac/notifications \ No newline at end of file diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml new file mode 100644 index 0000000..9a42b42 --- /dev/null +++ b/.trunk/trunk.yaml @@ -0,0 +1,11 @@ +version: 0.1 +cli: + version: 1.2.1 +lint: + enabled: + - git-diff-check@SYSTEM + - gitleaks@8.9.0 + - markdownlint@0.32.1 + - prettier@2.7.1 + - shellcheck@0.8.0 + - shfmt@3.5.0 diff --git a/CMakeLists.txt b/CMakeLists.txt index 60ccd92..d784e7c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,7 @@ find_package(RapidJSON CONFIG REQUIRED) find_package(fmt CONFIG REQUIRED) find_package(Catch2 CONFIG REQUIRED) find_package(cxxopts CONFIG REQUIRED) -#find_package(Poco CONFIG REQUIRED COMPONENTS Net JSON Util) +find_package(Poco CONFIG REQUIRED COMPONENTS Net JSON Util) find_package(libzip CONFIG REQUIRED) find_package(SQLiteCpp CONFIG REQUIRED) @@ -36,9 +36,6 @@ set(INCLUDE_DIRS "include" "/usr/include/doctest" ${RAPIDJSON_INCLUDE_DIRS} - # Poco::Net - # Poco::JSON - #Poco::Util ) set(LINK_LIBS fmt::fmt @@ -46,9 +43,6 @@ set(LINK_LIBS Catch2::Catch2 cxxopts::cxxopts SQLiteCpp - #Poco::Net - #Poco::JSON - #Poco::Util -lcurlpp -lzip -lsqlite3 diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index a263968..0000000 --- a/Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -FROM cgr.dev/chainguard/wolfi-base - -RUN apk add --no-cache tini - -# run as nobody -USER 65534:65534 - - -# build the binary then copy into container -RUN bin/compile.sh --link -RUN bin/compile.sh --all - -COPY build/gdpm.static /gdpm - -CMD ["/gdpm"] - -ENTRYPOINT [ "/sbin/tini", "--" ] \ No newline at end of file diff --git a/README.md b/README.md index 22c64eb..95e2517 100644 --- a/README.md +++ b/README.md @@ -7,26 +7,24 @@ GDPM is an attempt to make a simple, front-end, command-line, package manager de \*GDPM has not been tested for Windows or Mac. -- [Godot Package Manager (GDPM)](#godot-package-manager-gdpm) - - [Quick Start](#quick-start) - - [Rationale](#rationale) - - [How It Works](#how-it-works) - - [Features](#features) - - [Installing with Package Managers](#installing-with-package-managers) - - [Building from Source](#building-from-source) - - [Prerequisites](#prerequisites) - - [Macro Definitions](#macro-definitions) - - [API Documentation](#api-documentation) - - [How to use the CLI](#how-to-use-the-cli) - - [Installing, Removing, Updating, and Listing](#installing-removing-updating-and-listing) - - [Searching](#searching) - - [Linking and Cloning](#linking-and-cloning) - - [Cleaning Temporary Files](#cleaning-temporary-files) - - [Managing Remote Sources](#managing-remote-sources) - - [Managing Configuration Properties](#managing-configuration-properties) - - [Planned Features](#planned-features) - - [Known Issues](#known-issues) - - [License](#license) +- [Quick Start](#quick-start) +- [Rational](#rationale) +- [How It Works](#how-it-works) +- [Features](#features) +- [Building from Source](#building-from-source) + - [Prerequisites](#prerequisites) + - [Macro Definitions](#macro-definitions) + - [API Documentation](#api-documentation) +- [How to use the CLI](#how-to-use-the-cli) + - [Installing, Removing, Updating, and Listing](#installing-removing-updating-and-listing) + - [Searching](#searching) + - [Linking and Cloning](#linking-and-cloning) + - [Cleaning Temporary Files](#cleaning-temporary-files) + - [Managing Remote Sources](#managing-remote-sources) + - [Managing Configuration Properties](#managing-configuration-properties) +- [Planned Features](#planned-features) +- [Known Issues](#known-issues) +- [License](#license) @@ -35,16 +33,10 @@ GDPM is an attempt to make a simple, front-end, command-line, package manager de Common commands for searching, installing, listing, and removing assets. ```bash -# fetch updates local database if "no packages to install" error -gdpm fetch - -# search and install "Godot Jolt" globally -gdpm search jolt -gdpm install "Godot Jolt" --skip-prompt - -# list installed packages and remove +gdpm search demo +gdpm install "Third Person Controller" --skip-prompt gdpm list --style=table -gdpm remove "Godot Jolt" --clean +gdpm remove "Third Person Controller" --clean ``` Use `gdpm help` to see full list of commands. @@ -106,20 +98,6 @@ The local database stores all the information sent by the Asset API with additio * Export list of installed packages to reinstall later. -* Parallel downloads using `libcurl`. - - -## Installing with Package Managers - -Currently, `gdpm` can only be installed using `makepkg` on Arch Linux with plans of packaging for other distributions in the future. - -```bash -git clone https://github.com/davidallendj/gdpm && cd gdpm/dist/archlinux -makepkg -si -``` - -This should build the static binary from source and then install it in `/usr/bin/gdpm`. - ## Building from Source The project uses the CMake or Meson build system and has been tested with GCC and Clang on Arch/Manjaro Linux. CMake is preferred, but a `meson.build` script is provided and should work with some tweaking. Building on Windows or Mac has not been tested yet so it's not guaranteed to work. Compiling with CMake will build 2 executables, 3 shared libraries, and an archive library to link, while compiling with Meson only builds an executable that links with a shared library. @@ -138,63 +116,32 @@ The project uses the CMake or Meson build system and has been tested with GCC an * fmt (may be removed later in favor of C++20 std::format) -* SQLite 3 and SQLite C++ wrapper - -* cxxopts +* SQLite 3 * doctest (optional; for tests, but still WIP) * Doxygen (optional; to generate API docs) -Arch Linux users can simply install required libs through `pacman` and/or `yay`: - -```bash -pacman -S base-devel fmt sqlite rapidjson cmake libzip curl catch2 cxxopts doctest -yay -S sqlitecpp libcurlpp -``` - -After installing the packages, clone the submodules and link the headers: - -```bash -git submodule add https://github.com/p-ranav/argparse modules/argparse -git submodule add https://github.com/p-ranav/tabulate modules/tabulate -git submodule add https://github.com/p-ranav/indicators modules/indicators -git submodule add https://github.com/p-ranav/csv2 modules/csv2 - -ln -s ../modules/argparse/include/argparse include/argparse -ln -s ../modules/tabulate/include/tabulate include/tabulate -ln -s ../modules/indicators/include/indicators include/indicators -ln -s ../modules/csv2/include/csv2 include/csv2 -``` - -Otherwise, you can just update the modules if they're already there and out-of-date: - -```bash -git submodule update --init --recursive -``` - -And then build the binaries (check the "build" directory): +After installing all necessary dependencies, build the project:: ```bash # Start by cloning the repo, then... -git clone https://github.com/davidallendj/gdpm && cd gdpm - -# ... if using CMake with Ninja instead (preferred and tested)... -cmake -B build -S . -D CMAKE_EXPORT_COMPILE_COMMANDS=1 -D CMAKE_BUILD_TYPE=Release -G Ninja -ninja -C build -j$(nproc) +git clone https://github.com/davidallendj/gdpm +cd gdpm +export project_root=${pwd} # ...if using Meson with Clang on Linux... meson build meson configure build # only needed if reconfiguring build meson compile -C build -j$(nproc) -CXX=clang++ meson compile -C build -j$(nproc) +CXX=clang++ meson compile -C build -j$(npoc) -# ...if using CMake with Make on Linux (needs work!)... +# ...if using CMake on Linux (needs work!)... cd build cmake .. make -j$(nproc) -# Easy build using predefined `compile` script +# Easy build using predefined `compile` script ${project_root}/bin/compile.sh --all @@ -280,19 +227,6 @@ $ gdpm export path/to/packages.txt $ gdpm install -f path/to/packages.txt --sync=disable --skip-prompt ``` -If you get a "no packages found to install" error message, try doing a `gdpm fetch` to update the local cache database, then try again. - -```bash -$ gdpm install "Godot Jolt" -[ERROR 07:18:41 PM; 2024-03-03] package::install(): no packages found to install. -$ gdpm fetch  ✔ -[INFO 07:19:19 PM; 2024-03-03] Sychronizing database...Done. -$ gdpm install "Godot Jolt"  ✔ - Title Author Category Version Godot Last Modified Installed? - Godot Jolt mihe Misc 16 4.2 2024-01-08 11:10:46 ❌ -Do you want to install these packages? (Y/n) -``` - If you leave out the `--skip-prompt` flag, hit enter to install by default. ```bash @@ -404,9 +338,7 @@ $ gdpm config set username towk - [x] Parallel downloading. -- [X] PKGBUILD for ArchLinux/Manjaro. - -- [X] Dockerfile to run in sandbox. +- [ ] PKGBUILD for ArchLinux/Manjaro. - [ ] Proper updating. @@ -418,17 +350,17 @@ $ gdpm config set username towk - [ ] Adapted to new Asset API. -- [ ] Unit tests. - - [ ] User interface. - [ ] Experimental dependency management. There is no way of handling dependencies using the Godot Asset API. This is a [hot topic](https://github.com/godotengine/godot-proposals/issues/142) and might change in the near future. ## Known Issues -* Logging doesn't write to file yet. +* The code is currently still changing so API is unstable. + +* Logging doesn't write to file. * Download progress bars are not showing when downloading archives. This is being reworked to display multiple bars dynamically to better show download status. ## License -See the `LICENSE.md` file. +See the LICENSE.md file. diff --git a/SConstruct b/SConstruct deleted file mode 100644 index 7dac6ec..0000000 --- a/SConstruct +++ /dev/null @@ -1,25 +0,0 @@ - -# set up variables and glob files -env = Environment( - CPPPATH = Glob('include/*.hpp'), - CPPDEFINES = [], - LIBS = [] -) -base_name = "gdpm" -include_files = Glob('include/*.hpp') -source_files = Glob('src/*.cpp') -test_files = Glob('tests/*.cpp') -compile_flags = "" - -# build the main executable and tests -env.Program(f'{base_name}', source_files) -env.Program(f'{base_name}.tests', test_files) - -# build the static library -StaticLibrary(f'{base_name}-static') - -# build the shared libraries -SharedLibrary(f'{base_name}-shared') -SharedLibrary(f'{base_name}-static') -SharedLibrary(f'{base_name}-http') -SharedLibrary(f'{base_name}-restapi') diff --git a/bin/compile.sh b/bin/compile.sh index 01a94df..3042f09 100755 --- a/bin/compile.sh +++ b/bin/compile.sh @@ -46,16 +46,6 @@ function link_all(){ link_exe $script_dir/../build/gdpm.tests $script_dir/../bin/$tests } -function get_deps() { - #git submodule init -f - #git submodule init -f - - # link the include headers - ln -s ../modules/indicators/include/indicators include/indicators - ln -s ../modules/tabulate/include/tabulate include/tabulate - ln -s ../modules/argparse/include/argparse include/argparse -} - function clean(){ rm ${script_dir}/../bin/$exe @@ -63,12 +53,6 @@ function clean(){ rm ${script_dir}/../bin/$tests } -function checksums(){ - sha256sums ${script_dir}/../bin/$exe - sha256sums ${script_dir}/../bin/$static - sha256sums ${script_dir}/../bin/$tests -} - # Run this script at project root #meson configure build #CXX=clang++ meson compile -C build -j$(proc) @@ -88,7 +72,6 @@ function build_all(){ function build_exe(){ mkdir -p build $CMAKE_COMMAND \ - --build . \ --target gdpm \ --target gdpm.static $NINJA_COMMAND @@ -98,7 +81,6 @@ function build_exe(){ function build_libs(){ mkdir -p build $CMAKE_COMMAND \ - --build . \ --target gdpm-static \ --target gdpm-shared \ --target gdpm-http \ @@ -108,7 +90,7 @@ function build_libs(){ function build_tests(){ mkdir -p build - $CMAKE_COMMAND --build . --target gdpm.tests + $CMAKE_COMMAND --target gdpm.tests $NINJA_COMMAND } @@ -136,8 +118,6 @@ do --exe) build_exe shift;; --libs) build_libs shift;; --tests) build_tests shift;; - --deps) get_deps shift;; - --sums) checksums shift;; -d|--docs) build_docs shift;; -c|--clean) clean shift;; -s|--strip) strip_all shift;; diff --git a/dist/archlinux/PKGBUILD b/dist/archlinux/PKGBUILD deleted file mode 100644 index 0086697..0000000 --- a/dist/archlinux/PKGBUILD +++ /dev/null @@ -1,56 +0,0 @@ -# Maintainer: David J. Allen -pkgname=gdpm-git -pkgver=r94.341f075 -pkgrel=1 -pkgdesc="CLI tool to automate managing Godot game engine assets from the command-line. This includes a pre-built, static binary." -arch=('x86_64') -url="https://github.com/davidallendj/gdpm" -license=('MIT') -depends=('glibc') -makedepends=('cmake' 'ninja' 'clang' 'gcc') -optdepends=('meson' 'make') -source=("$pkgname-$pkgver::git+https://github.com/davidallendj/gdpm") -sha256sums=('SKIP') - -pkgver() { - printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)" -} - -prepare() { - cd "$srcdir/$pkgname-$pkgver" - - # remove all links to modules - rm -f include/argparse - rm -f include/tabulate - rm -f include/indicators - rm -f include/csv2 - - # update and initialize submodules - git submodule update --init modules/argparse - git submodule update --init modules/tabulate - git submodule update --init modules/indicators - git submodule update --init modules/csv2 - - # link module headers to include/* - ln -s ../modules/argparse/include/argparse include/argparse - ln -s ../modules/tabulate/include/tabulate include/tabulate - ln -s ../modules/indicators/include/indicators include/indicators - ln -s ../modules/csv2/include/csv2 include/csv2 -} - -build () { - cd "$srcdir/$pkgname-$pkgver" - bin/compile.sh --all -} - -package() { - cd "$srcdir/$pkgname-$pkgver" - - # install the binary to /usr/bin - mkdir -p "${pkgdir}/usr/bin" - install -m755 build/gdpm.static "${pkgdir}/usr/bin/gdpm" -} - -clean() { - rm -rf "$srcdir/$pkgname-$pkgver" -} diff --git a/include/argparse b/include/argparse deleted file mode 120000 index 5eb5bec..0000000 --- a/include/argparse +++ /dev/null @@ -1 +0,0 @@ -../modules/argparse/include/argparse \ No newline at end of file diff --git a/include/cache.hpp b/include/cache.hpp index fdf1aea..75801e3 100644 --- a/include/cache.hpp +++ b/include/cache.hpp @@ -16,7 +16,6 @@ namespace gdpm::cache { string table_name = GDPM_PACKAGE_CACHE_TABLENAME; }; - bool exists(const params& = params()); error create_package_database(bool overwrite = false, const params& = params()); error insert_package_info(const package::info_list& packages, const params& = params()); result_t get_package_info_by_id(const package::id_list& package_ids, const params& = params()); diff --git a/include/config.hpp b/include/config.hpp index 5fc0fba..3d2a135 100644 --- a/include/config.hpp +++ b/include/config.hpp @@ -31,7 +31,6 @@ namespace gdpm::config{ bool enable_sync = true; bool enable_cache = true; bool skip_prompt = false; - bool ignore_validation = false; bool enable_file_logging; bool clean_temporary; diff --git a/include/error.hpp b/include/error.hpp index 8ce1b33..59bacb3 100644 --- a/include/error.hpp +++ b/include/error.hpp @@ -11,7 +11,7 @@ namespace gdpm::constants::error{ enum class ec{ - IGNORE = 0, + NONE = 0, UNKNOWN, UNKNOWN_COMMAND, UNKNOWN_ARGUMENT, @@ -93,7 +93,7 @@ namespace gdpm{ namespace ce = constants::error; class error { public: - constexpr explicit error(ec code = ec::IGNORE, const string& message = "{default}"): + constexpr explicit error(ec code = ec::NONE, const string& message = "{default}"): m_code(code), m_message(utils::replace_all(message, "{default}", ce::get_message(code))) {} diff --git a/include/rest_api.hpp b/include/rest_api.hpp index 0c11c1f..efcc351 100644 --- a/include/rest_api.hpp +++ b/include/rest_api.hpp @@ -53,7 +53,7 @@ namespace gdpm::rest_api{ int support; string user = ""; string cost = ""; - string godot_version = "4.3"; + string godot_version = "4.0"; int max_results = 500; int page; int offset; diff --git a/include/types.hpp b/include/types.hpp index 1ccc1bc..6896f0e 100644 --- a/include/types.hpp +++ b/include/types.hpp @@ -8,7 +8,6 @@ #include #include #include -#include namespace gdpm{ class error; diff --git a/include/utils.hpp b/include/utils.hpp index dfebb51..3a75be3 100644 --- a/include/utils.hpp +++ b/include/utils.hpp @@ -78,11 +78,6 @@ namespace gdpm::utils { return a; } - template - std::string format(std::string_view fmt, Args&&...args){ - return std::vformat(fmt, std::make_format_args(args...)); - } - bool to_bool(const std::string& s); std::vector split_lines(const std::string& contents); std::string readfile(const std::string& path); @@ -102,7 +97,6 @@ namespace gdpm::utils { std::string join(const std::vector& target, const std::string& delimiter = ", "); std::string join(const std::unordered_map& target, const std::string& prefix = "", const std::string& delimiter = "\n"); std::string convert_size(long size); - // TODO: Add function to get size of decompressed zip namespace json { diff --git a/include/version.hpp b/include/version.hpp index 881646a..b06715f 100644 --- a/include/version.hpp +++ b/include/version.hpp @@ -1,20 +1,14 @@ #pragma once -#include "error.hpp" -#include "result.hpp" - #include - namespace gdpm::version{ - struct context{ - int major = 0; - int minor = 0; - int patch = 0; - string description = ""; + struct version_context{ + int major; + int minor; + int patch; }; - std::string to_string(const context& context); - result_t to_version(const std::string& version); - bool is_valid_version_string(const std::string& version); + std::string to_string(const version_context& context); + version_context to_version(const std::string& version); } \ No newline at end of file diff --git a/modules/clipp b/modules/clipp new file mode 160000 index 0000000..02783b6 --- /dev/null +++ b/modules/clipp @@ -0,0 +1 @@ +Subproject commit 02783b6782ebedbb2bebc2e6ceda738ee51c7df2 diff --git a/modules/indicators b/modules/indicators deleted file mode 160000 index 222382c..0000000 --- a/modules/indicators +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 222382c3a6abbce32503792c59826063660ddb56 diff --git a/src/cache.cpp b/src/cache.cpp index 45546ad..09b62a2 100644 --- a/src/cache.cpp +++ b/src/cache.cpp @@ -17,10 +17,6 @@ namespace gdpm::cache{ return utils::replace_all(s, "'", "''"); } - bool exists(const params& params) { - return std::filesystem::exists(params.cache_path); - } - error create_package_database( bool overwrite, const params& params diff --git a/src/config.cpp b/src/config.cpp index fc00107..c501b31 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -343,7 +343,7 @@ namespace gdpm::config{ error.set_message("Key `remote_sources` is not a JSON object."); return error; } - error.set_code(ec::IGNORE); + error.set_code(ec::NONE); return error; } diff --git a/src/main.cpp b/src/main.cpp index 0891df9..5b73e29 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,10 @@ // Godot Package Manager (GPM) - +#include "constants.hpp" +#include "log.hpp" +#include "config.hpp" #include "package_manager.hpp" +#include "result.hpp" #include @@ -10,13 +13,7 @@ int main(int argc, char **argv){ using namespace gdpm::package_manager; error error = initialize(argc, argv); - if(error.has_occurred()) { - log::error(error); - } - error = parse_arguments(argc, argv); - if(error.has_occurred()) { - log::error(error); - } + parse_arguments(argc, argv); finalize(); return EXIT_SUCCESS; diff --git a/src/package.cpp b/src/package.cpp index d44d2cd..5fbd21a 100644 --- a/src/package.cpp +++ b/src/package.cpp @@ -58,7 +58,7 @@ namespace gdpm::package{ if(p_cache.empty()){ return log::error_rc( ec::NOT_FOUND, /* TODO: change to PACKAGE_NOT_FOUND */ - "package::install(): no package(s) found to install." + "package::install(): no packages found to install." ); } diff --git a/src/package_manager.cpp b/src/package_manager.cpp index 2713bd7..924ff03 100644 --- a/src/package_manager.cpp +++ b/src/package_manager.cpp @@ -147,13 +147,6 @@ namespace gdpm::package_manager{ .help("set verbosity level") .nargs(nargs_pattern::optional); - program.add_argument("--ignore-validation") - .action([&](const auto&){ config.ignore_validation = true; }) - .default_value(false) - .implicit_value(true) - .help("ignore checking if current directory is a Godot project") - .nargs(0); - install_command.add_description("install package(s)"); install_command.add_argument("packages") .required() @@ -416,13 +409,6 @@ namespace gdpm::package_manager{ return log::error_rc(ec::ARGPARSE_ERROR, e.what()); } - /* Check if we're running in a directory with 'project.godot' file */ - if (!config.ignore_validation) { - if(!std::filesystem::exists("project.godot")){ - return error(ec::FILE_NOT_FOUND, "no 'project.godot' file found in current directory"); - } - } - if(program.is_subcommand_used(install_command)){ action = action_e::install; // if(install_command.is_used("packages")) diff --git a/src/rest_api.cpp b/src/rest_api.cpp index b73268f..0691146 100644 --- a/src/rest_api.cpp +++ b/src/rest_api.cpp @@ -12,6 +12,10 @@ #include #include +#include +#include +#include +#include namespace gdpm::rest_api{ diff --git a/src/utils.cpp b/src/utils.cpp index 3277f49..b71c2c2 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -313,7 +313,7 @@ namespace gdpm::utils{ case 5: return s + " PB"; } return std::to_string(size); - } + } namespace json { string from_array( diff --git a/src/version.cpp b/src/version.cpp index 9cf8922..167f502 100644 --- a/src/version.cpp +++ b/src/version.cpp @@ -1,35 +1,16 @@ - #include "version.hpp" -#include - namespace gdpm::version{ - - void print(){ - - } - string to_string(const context& c){ - return utils::format("{}.{}.{}", c.major, c.minor, c.patch); + std::string to_string(const version_context& context){ + return std::string(); } - result_t to_version(const string& version){ - context v; + version_context to_version(const std::string& version){ + version_context v; - // check if string is valid - if(!is_valid_version_string(version)){ - return result_t(context(), error(ec::IGNORE, "invalid version string")); - } - - // convert string to version context - - - return result_t(v, error()); - } - - bool is_valid_version_string(const string &version){ - return std::regex_match(version, std::regex("^(\\d+\\.)?(\\d+\\.)?(\\*|\\d+)$")); + return v; } } \ No newline at end of file diff --git a/submodules/indicators b/submodules/indicators new file mode 160000 index 0000000..ef71abd --- /dev/null +++ b/submodules/indicators @@ -0,0 +1 @@ +Subproject commit ef71abd9bc7254f7734fa84d5b1c336be2deb9f7