Skip to content

File nptool.cxx

File List > src > utility > nptool.cxx

Go to the documentation of this file

#include <errno.h>
#include <stdio.h>
#include <string.h>

#include <fstream>
#include <iostream>
#include <string>

#include "NPApplication.h"
#include "NPException.h"
#include "NPInputParser.h"
#include "NPTerminalColor.h"

// function
// env
void new_env(std::string);
void remove_env(std::string);
bool check_env(std::string);

// package management
void install(std::string, bool allow_branch = true);
void reinstall(std::string, bool allow_branch = true);
void update(std::string);
void uninstall(std::string);
bool check_install(std::string);
bool update_remote();

// project
std::string check_project(std::string);
void new_project(std::string);
void remove_project(std::string);
void mv_project(std::string);
void duplicate(std::vector<std::string>);

std::string PWD;
std::string Path;
std::string Home;
std::string Env;
std::string Log;
std::string LogShell;
std::string check;
std::string cross;

// Platform dependent sed command
#ifdef __linux__
std::string sed = "sed -i ";
std::string lib_extention = ".so";
#endif

#ifdef __FreeBSD__
std::string sed = "sed -i \'\' -e ";
std::string lib_extention = ".so"
#endif

#ifdef __APPLE__
    std::string sed = "sed -i \'\' -e ";
std::string lib_extention = ".dylib";
#endif

int execute_command(std::string& command, bool login = true, bool output = true) {
  std::string cmd = command;
  if (login) {
    cmd = "echo \"**** executing command: " + command + "\" " + LogShell;
    system(cmd.c_str());
    if (output) {
      cmd = command + LogShell;
    }
    else
      cmd = command;
  }
  return system(cmd.c_str());
}

int main(int argc, char** argv) {
  std::cout << nptool::cli_blue << nptool::cli_horizontal;
  std::cout << "                     nptool v0.1 environment utility           "
               "                \n";
  std::cout << nptool::cli_horizontal << nptool::cli_restore_color << std::endl;
  PWD = getenv("PWD");
  Path = getenv("NPTOOL");
  Home = getenv("NPTOOL_HOME");
  if (Home.back() != '/')
    Home += "/";
  Env = Home + getenv("NPTOOL_ENV");
  Log = Env + "/nptool.log";
  LogShell = " >> " + Log + " 2>&1";
  check = nptool::cli_green + "  \u2713  " + nptool::cli_blue;
  cross = nptool::cli_red + "  \u2718  " + nptool::cli_blue;

  try {
    // instantiate an application
    auto app = nptool::Application::InitApplication(argc, argv, 1);
    app->Start(false);

    // Checking the correct number of argument is given:
    if (app->NumberOfFlags() == 0) {
      std::string msg = "No flags provided";
      nptool::Error ex("nptool", msg);
      throw ex;
    }

    if (app->HasFlag("-h")) {
      system("man nptool");
      return 0;
    }
    // If new-env flag is present: //
    else if (app->HasFlag("--new-env")) {
      std::string env = app->GetArg("--new-env");
      if (!check_env(env))
        new_env(env);
      else
        throw nptool::Error("nptool", "Environment \"" + env + "\" already exist.",
                            "Remove with nptool --remove-env " + env);
    }

    // If remove-env flag is present: //
    else if (app->HasFlag("--remove-env")) {
      std::string env = app->GetArg("--remove-env");
      if (check_env(env))
        remove_env(env);
      else
        throw nptool::Warning("nptool", "Environment \"" + env + "\" does not exist.");
    }

    // If update-remote flag is present: //
    else if (app->HasFlag("--update-remote")) {
      if (!update_remote())
        throw nptool::Warning("nptool", "Fail to update remote package list");
    }

    // If install flag is present: //
    else if (app->HasFlag("--install")) {
      std::vector<std::string> List = app->GetVectorArg("--install");
      std::cout << nptool::cli_blue << "**** Package installation: \n";
      for (unsigned int i = 0; i < List.size(); i++) {
        install(List[i]);
      }
      std::cout << std::flush;
    }

    // If update flag is present: //
    else if (app->HasFlag("--update")) {
      std::vector<std::string> List = app->GetVectorArg("--update");
      std::cout << nptool::cli_blue << "**** Package update of " << List.size() << " packages: \n";
      for (unsigned int i = 0; i < List.size(); i++) {
        update(List[i]);
      }
      std::cout << std::flush;
    }

    // If uninstall flag is present: //
    else if (app->HasFlag("--uninstall")) {
      std::vector<std::string> List = app->GetVectorArg("--uninstall");
      std::cout << nptool::cli_blue << "**** Package uninstallation: \n";
      for (unsigned int i = 0; i < List.size(); i++) {
        uninstall(List[i]);
      }
      std::cout << std::flush;
    }

    // If reinstall flag is present: //
    else if (app->HasFlag("--reinstall")) {
      std::vector<std::string> List = app->GetVectorArg("--reinstall");
      std::cout << nptool::cli_blue << "**** Package reinstallation: \n";
      for (unsigned int i = 0; i < List.size(); i++) {
        reinstall(List[i]);
      }
      std::cout << std::flush;
    }

    // If new project flag is present: //
    else if (app->HasFlag("--new-project")) {
      std::string List = app->GetArg("--new-project");
      std::cout << nptool::cli_blue << "**** Project creation: \n";
      new_project(List);
      std::cout << std::flush;
    }

    // If remove-project flag is present: //
    else if (app->HasFlag("--remove-project")) {
      std::string List = app->GetArg("--remove-project");
      std::cout << nptool::cli_blue << "**** Project deletion: \n";
      remove_project(List);
      std::cout << std::flush;
    }
    else if (app->HasFlag("--duplicate")) {
      std::vector<std::string> List = app->GetVectorArg("--duplicate");
      std::cout << nptool::cli_blue << "**** Plugin duplicate: \n";
      duplicate(List);
      std::cout << std::flush;
    }

    std::cout << nptool::cli_blue << nptool::cli_horizontal;
    app->Stop();
  }

  // catch any exception that was not deal with before
  catch (nptool::Exception& ex) {
    nptool::DisplayException(ex);
    return 1;
  }
  // to do list:
  // - duplicate -> local version of the package
  // - switch-env -> use existing env in home
  return 0;
}
void uninstall(std::string package) {
  std::cout << nptool::cli_blue;
  std::cout << "** " << package << std::endl;

  // Userful variable
  // path
  std::string Package = Env + "/" + package;
  std::string Build = Package + "/build";
  std::string Sources = Package + "/sources";
  std::string Manifest = Build + "/install_manifest.txt";
  std::ifstream manifest(Manifest);
  if (!manifest.is_open()) {
    std::string msg = "install_manifest.txt not found for package " + package;
    Manifest = "expecting file \"" + Manifest + "\"";
    throw nptool::Error("nptool", msg, Manifest);
  }

  // remove installed file
  std::string file;
  while (manifest >> file) {
    std::string command = "rm " + file;
    if (execute_command(command) != 0) {
      std::string msg = " fail to execute \"" + command + "\"";
      throw nptool::Error("nptool", msg);
    }
    else
      std::cout << check << " Removing file " << file << std::endl;
  }

  // remove installed lib
  std::ifstream pl(Env + "/plugin_lib.list");
  if (!pl.is_open()) {
    std::string msg = "plugin_lib.list not found ";
    throw nptool::Error("nptool", msg);
  }
  std::string stoken, spackage, slib;
  while (pl >> stoken >> spackage >> slib) {
    if (spackage == package) {
      std::string command = "rm " + Env + "/lib/" + slib;
      if (execute_command(command) != 0) {
        std::string msg = " fail to execute \"" + command + "\"";
        throw nptool::Error("nptool", msg);
      }
      else
        std::cout << check << " Removing file " << slib << std::endl;
    }
  }

  // remove folder
  std::string command = "rm -Rf " + Package;
  if (execute_command(command) != 0) {
    std::string msg = " fail to execute \"" + command + "\"";
    throw nptool::Error("nptool", msg);
  }
  else
    std::cout << check << " Removing folder " << Package << std::endl;

  // remove from installed
  command = sed + "\'/^" + package + "/d\' " + Env + "/installed_package.list";
  if (execute_command(command) != 0) {
    std::string msg = " fail to execute \"" + command + "\"";
    throw nptool::Error("nptool", msg);
  }
  else
    std::cout << check << " Package removed from installed list " << std::endl;

  // remove from package_lib
  command = sed + "\'/^" + package + "/d\' " + Env + "/plugin_lib.list";
  if (execute_command(command) != 0) {
    std::string msg = " fail to execute \"" + command + "\"";
    throw nptool::Error("nptool", msg);
  }
  else
    std::cout << check << " Package removed from library list " << std::endl;
}
void install(std::string package, bool allow_branch) {
  update_remote();
  std::cout << nptool::cli_blue;
  std::cout << "** " << package << std::endl;

  // Userful varialbe
  // path
  std::string Package = Env + "/" + package;
  std::string Build = Package + "/build";
  std::string Sources = Package + "/sources";

  // check if package is installed
  if (check_install(package)) {
    std::cout << check << " " << package << " already installed" << std::endl;
    return;
  }

  // check if branch and/or commit option are given
  std::string branch_or_commit = "xx_void_xx";
  if (allow_branch) {
    auto app = nptool::Application::GetApplication();
    if (app->HasFlag("--branch")) {
      auto arg = app->GetVectorArg("--branch");
      if (arg.size() == 1)
        branch_or_commit = arg[0];
      else {
        throw nptool::Error("nptool", "branch flag take one value only");
      }
    }
    if (app->HasFlag("--commit")) {
      auto arg = app->GetVectorArg("--commit");
      if (arg.size() == 1)
        branch_or_commit = arg[0];
      else
        throw nptool::Error("nptool", "commit flag take one value only");
    }
  }

  // exe and cmake option
  std::string cmake_generator = getenv("NPTOOL_GENERATOR");
  std::string cmake, make_bin;
  if (cmake_generator.compare("Ninja") == 0) {
    make_bin = "ninja ";
    cmake = "cmake -GNinja -Dnptool=1";
  }
  else {
    make_bin = "make ";
    cmake = "cmake -Dnptool=1";
  }

  // find the remote package list in the nptool folder
  std::string remote = Env + "/remote_package.list";
  std::ifstream remote_list(remote.c_str());
  if (remote_list.is_open()) {
    std::string name, url, command;
    while (remote_list >> name >> url) {
      if (name.compare(package) == 0) {
        // get the package file
        command = "curl -s " + url + " > /tmp/nptool_package ";
        if (execute_command(command, true, false) == 0)
          std::cout << " " << check << " package file checkout -> ";
        else
          throw nptool::Error("nptool", "fail to checkout package file at " + url);

        // read the package file
        nptool::InputParser parser("/tmp/nptool_package", true);
        system("rm /tmp/nptool_package > /dev/null");
        auto blocks = parser.GetAllBlocksWithToken("Package");

        if (blocks.size() > 0) {
          // checking dependencies:
          auto dependencies = blocks[0]->GetVectorString("dependencies");
          if (dependencies[0] != "null") {
            std::cout << "** installing dependencies " << std::endl;
            for (auto it = dependencies.begin(), end = dependencies.end(); it != end; it++) {
              install(*it, false); // false to ignore commit or branch flag on
                                   // dependencies
            }
            std::cout << "** dependencies done " << std::endl;
          }
          // repository url
          url = blocks[0]->GetString("url", true);
          // git clone
          command = "git clone " + url + " " + Sources;
          if (execute_command(command) == 0)
            std::cout << " " << check << " cloning repository from " << url << std::endl;
          else
            throw nptool::Error("nptool", "fail to clone repository at " + url);

          // checkout branch or commit if specified
          if (branch_or_commit.compare("xx_void_xx") != 0) {
            command = "git --git-dir=" + Sources + "/.git checkout -f " + branch_or_commit;
            if (execute_command(command) == 0) {
              std::cout << " " << check << " switching to " << branch_or_commit << std::endl;
            }
            else {
              std::string msg = "fail to checkout " + branch_or_commit + " from " + url;
              throw nptool::Error("nptool", msg);
            }
          }

          // cmake configuration
          command = cmake + " -S" + Sources + " -B" + Build + " -DCMAKE_INSTALL_PREFIX=" + Env;

          if (execute_command(command) == 0)
            std::cout << " " << check << " cmake config " << std::endl;
          else {
            // remove folder
            std::string command = "rm -Rf " + Package;
            if (execute_command(command) != 0) {
              std::string msg = " fail to clean up with \"" + command + "\"";
              throw nptool::Error("nptool", msg);
            }
            throw nptool::Error("nptool", "fail to run cmake for package ");
          }
          // compile
          command = make_bin + " -C " + Build;
          if (execute_command(command) == 0)
            std::cout << " " << check << " compilation " << std::endl;
          else {
            // remove folder
            std::string command = "rm -Rf " + Package;
            if (execute_command(command) != 0) {
              std::string msg = " fail to clean up with \"" + command + "\"";
              throw nptool::Error("nptool", msg);
            }
            throw nptool::Error("nptool", "fail to compile package ");
          }

          // install
          command = make_bin + " install -C " + Build;
          if (execute_command(command) == 0)
            std::cout << " " << check << " installation " << std::endl;
          else
            throw nptool::Error("nptool", "fail to install package ");

          // plugin registration
          auto plugins = parser.GetAllBlocksWithToken("Plugin");
          for (auto it = plugins.begin(), end = plugins.end(); it != end; it++) {
            auto token = (*it)->GetString("token", true);
            auto lib = (*it)->GetString("library", true);

            command =
                "echo \"" + package + " " + token + " lib" + lib + lib_extention + "\" >> " + Env + "/plugin_lib.list ";
            if (execute_command(command, true, false) == 0)
              std::cout << " " << check << " plugin " << token << " registration " << std::endl;
            else
              throw nptool::Error("nptool", "fail to register plugin");
          }
        }
        else
          throw nptool::Error("nptool", "Package \"" + package + "\" file does not contain appropriate token");
        // Success, record the package
        command = "echo \"" + package + "\" >> " + Env + "/installed_package.list ";
        execute_command(command, true, false);

        return;
      }
    }
    throw nptool::Error("nptool", "Package \"" + package + "\" does not exist");
  }
  else
    throw nptool::Error("nptool", "Fail to open " + Path);
}

void reinstall(std::string package, bool allow_branch) {

  // check if package is installed
  if (check_install(package)) {
    std::cout << check << "Package " << package << " is installed, proceeding to reinstall" << std::endl;
  }
  else{
    throw nptool::Error("nptool", "Failed: Package "+ package + " is not installed, please use: nptool --install " + package);
  }
  uninstall(package);
  install(package, allow_branch);
}

void update(std::string package) {
  std::cout << nptool::cli_blue;
  std::cout << "** " << package << std::endl;

  // Userful variables
  // path
  std::string Package = Env + "/" + package;
  std::string Build = Package + "/build";
  std::string Sources = Package + "/sources";

  // check if package is installed
  if (check_install(package)) {
    std::cout << check << " " << package << " installed" << std::endl;
  }

  else {
    std::cout << cross << " " << package << " not installed" << std::endl;
    return;
  }

  // exe and cmake option
  std::string cmake_generator = getenv("NPTOOL_GENERATOR");
  std::string cmake, make_bin;
  if (cmake_generator.compare("Ninja") == 0) {
    make_bin = "ninja ";
    cmake = "cmake -GNinja -Dnptool=1";
  }
  else {
    make_bin = "make ";
    cmake = "cmake -Dnptool=1";
  }
  std::string command;
  // git status
  command = "LANG=\"en_EN\" git --git-dir=" + Sources + "/.git --work-tree=" + Sources +
    " fetch --dry-run 2>&1 | grep 'From' ";
  if (execute_command(command) != 0) {
    std::cout << check << " already up to date " << Sources << std::endl;
    return;
  }

  // git pull
  command = "git --git-dir=" + Sources + "/.git --work-tree=" + Sources + " pull ";
  if (execute_command(command) == 0)
    std::cout << check << " pull from repository in " << std::endl;
  else
    throw nptool::Error("nptool", "fail to pull from repository");

  // compile
  command = make_bin + " -C " + Build;
  if (execute_command(command) == 0)
    std::cout << check << " compilation " << std::endl;
  else
    throw nptool::Error("nptool", "fail to compile package ");

  // install
  command = make_bin + " install -C " + Build;
  if (execute_command(command) == 0)
    std::cout << check << " installation " << std::endl;
  else
    throw nptool::Error("nptool", "fail to install package ");

  return;
}

void new_env(std::string env) {
  std::string command, command2;
  std::cout << nptool::cli_blue;
  std::cout << "**** Setting up new environment: \"" << env << "\"\n";
  /*
  // test if Home folder exist
  command = "ls " + Home + " > /dev/null 2>&1";
  command2 = "mkdir " + Home;
  if (execute_command(command, false, false) == 0)
  std::cout << check << Home << " folder present " << std::endl;
  else if (execute_command(command, false, false) == 0)
  std::cout << check << Home << " successfully created " << std::endl;
  else {
  std::string msg = "Failed to create " + Home + " folder";
  throw nptool::Error("nptool", msg);
  }
  */
  // create the $NPTOOL_ENV/<env>
  command = "mkdir -p " + Home + env;
  if (execute_command(command, false, false) == 0)
    std::cout << check << Home << env << " successfully created " << std::endl;
  else {
    std::string msg = "Failed to create " + Home + env + " folder";
    throw nptool::Error("nptool", msg);
  }
  /*  // test if .config exist
      command = "ls ~/.config > /dev/null 2>&1";
      if (execute_command(command, false, false) == 0)
      std::cout << check << "~/.config folder present " << std::endl;
      else if (system("mkdir ~/.config") == 0)
      std::cout << check << "~/.config successfully created " << std::endl;
      else
      throw nptool::Error("nptool", "Failed to create .config folder");

  // create the .config/nptool
  command = "ls ~/.config/nptool > /dev/null 2>&1";
  if (execute_command(command, false, false) == 0)
  std::cout << check << "~/.config/nptool folder present " << std::endl;
  else if (system("mkdir ~/.config/nptool") == 0)
  std::cout << check << "~/.config/nptool successfully created " <<
  std::endl; else throw nptool::Error("nptool", "Failed to create
  ~/.config/nptool folder");

  // create the .config/nptool/<env>.config
  command = "touch ~/.config/nptool/" + env + ".config";
  if (execute_command(command, false, false) == 0)
  std::cout << check << "~/.config/nptool/" + env + ".config successfully
  created " << std::endl; else throw nptool::Error("nptool", "Failed to create
  ~/.config/nptool/" + env + ".config");
  */
  std::cout << std::flush << nptool::cli_restore_color;
}
void remove_env(std::string env) {
  std::cout << nptool::cli_blue;
  std::cout << "**** Removing environment: \"" << env << "\"\n";
  std::string command;
  command = "rm -Rf " + Home + env + " > /dev/null 2>&1";
  if (execute_command(command, false, false) == 0)
    std::cout << check << Home + env + " removed" << std::endl;
  command = "rm -Rf " + Home + env + " > /dev/null 2>&1";
  if (execute_command(command, false, false) == 0)
    std::cout << check << "~/.config/nptool/" + env + " removed" << std::endl;
}

bool check_env(std::string env) {
  std::string command;
  command = "ls " + Home + env + " > /dev/null 2>&1";
  std::cout << command << std::endl;
  if (execute_command(command, false, false) == 0)
    return true;

  command = "ls " + Home + env + " > /dev/null 2>&1";

  std::cout << command << std::endl;
  if (execute_command(command, false, false) == 0)
    return true;

  return false;
}
bool check_install(std::string package) {
  // Userful varialbe
  // path
  std::string Package = Env + "/" + package;
  std::string Build = Package + "/build";
  std::string Sources = Package + "/sources";

  // check if package is installed
  std::string Installed = Env + "/installed_package.list";
  std::ifstream installed(Installed);
  std::string line;
  while (installed >> line) {
    if (line.compare(package) == 0) {
      return true;
    }
  }
  return false;
}
std::string check_project(std::string project) {
  // Userful varialbe
  // path
  std::string Package = Env + "/" + project;

  // check if project exist
  std::string List = Env + "/project.list";
  std::ifstream existing(List);
  std::string name, ppath;
  while (existing >> name >> ppath) {
    if (name.compare(project) == 0) {
      return ppath;
    }
  }
  return "_none_";
}
void new_project(std::string project) {
  std::string command;
  std::cout << nptool::cli_blue;
  std::cout << "**** Setting up new project: \"" << project << "\"\n";

  // check if a project with same name exist:
  if (check_project(project).compare("_none_") != 0) {
    std::string msg = "A project exist already with the same name at " + check_project(project);
    throw nptool::Error("nptool", msg, "remove existing project or choose a different name");
  }

  // copy base file from resources
  command = "cp -R " + Path + "/resources/default_project " + project;
  if (execute_command(command) == 0)
    std::cout << check << project << " main direcotry successfully created " << std::endl;
  else
    throw nptool::Error("nptool", "Failed to create " + project + " directory");

  // make additional empty folder
  command = "mkdir " + project + "/calibration ";
  command += project + "/energy_loss ";
  command += project + "/detector ";
  command += project + "/output ";
  command += project + "/output/analysis ";
  command += project + "/output/simulation ";
  command += project + "/output/conversion ";
  if (execute_command(command) == 0)
    std::cout << check << project << " directory arborescence successfully created " << std::endl;
  else
    throw nptool::Error("nptool", "Failed to create " + project + " directory arborescence");

  // append folder path and name to list of project:
  command = "echo \"" + project + " " + PWD + "/" + project + "\" >> " + Env + "/project.list";

  // test if .config exist
  if (execute_command(command, true, false) == 0)
    std::cout << check << project << " append to projects list" << std::endl;
  else
    throw nptool::Error("nptool", "Failed to append to projects list");

  std::cout << std::flush << nptool::cli_restore_color;
}
void remove_project(std::string project) {
  std::string command;
  std::cout << nptool::cli_blue;
  std::cout << "**** Removing project: \"" << project << "\"\n";

  // check if a project with same name exist:
  if (check_project(project).compare("_none_") == 0) {
    std::string msg = "Project " + project + " not found in project list";
    throw nptool::Error("nptool", msg);
  }

  // remove the project folder
  command = "rm -Rf " + check_project(project) + LogShell;
  if (execute_command(command) == 0)
    std::cout << check << project << " folder successfully suppressed " << std::endl;
  else
    throw nptool::Error("nptool", "Failed to suppress " + check_project(project));

  // remove folder path and name from list of project:
  command = sed + "\'/^" + project + "/d\' " + Env + "/project.list";
  if (execute_command(command) == 0)
    std::cout << check << project << " removed from projects list" << std::endl;
  else
    throw nptool::Error("nptool", "Failed to removed from projects list");

  std::cout << std::flush << nptool::cli_restore_color;
}
void duplicate(std::vector<std::string> List) {
  std::string command, command2, command3;
  std::cout << nptool::cli_blue;
  // check if a project.yaml file is present in the current folder
  command = "ls project.yaml > /dev/null 2>&1";
  if (execute_command(command, false, false) == 0)
    std::cout << check << "project.yaml file present: valid project " << std::endl;
  else {
    std::string msg = "Not in a valid project folder ";
    std::string fix = "Run this command from a valid project folder";
    throw nptool::Error("nptool", msg, fix);
  }
  // load the project file
  nptool::InputParser parser("project.yaml", true);
  // loop over all plugin to duplicate locally
  for (auto it = List.begin(), end = List.end(); it != end; it++) {
    std::cout << "  ** Duplicating plugin: \"" << *it << "\"\n";
    // check that the plugin exist
    if (check_install(*it)) {
      std::cout << " " << check << *it << " is an installed plugin " << std::endl;
      auto blocks = parser.GetAllBlocksWithToken("project");
      auto already_duplicate = blocks[0]->GetVectorString("duplicate plugin", true);
      bool valid = true;
      for (auto itt = already_duplicate.begin(), aend = already_duplicate.end(); itt != aend; itt++) {
        if (*itt == *it) {
          std::cout << " " << cross << *it << " is already duplicated. Ignoring " << std::endl;
          valid = false;
          break;
        }
      }
      // Copy of the folder
      if (valid) {
        command = "cp -r " + Env + "/" + *it + "/sources " + *it;
        if (execute_command(command, true, false) == 0)
          std::cout << " " << check << *it << " folder copied " << std::endl;
        else {
          std::cout << " " << cross << *it << " folder copy failed " << std::endl;
          valid = false;
        }
      }

      // Adding the relevant folder to CMake
      if (valid) {
        command = "echo \"add_subdirectory(\"" + *it + "\")\">>duplicate.cmake";
        command2 = "echo \"include_directories(\\${duplicate_include_dir})\" >> "
          "duplicate.cmake ";
        command3 = "touch CMakeLists.txt";
        if (execute_command(command, false, false) == 0 && execute_command(command2, false, false) == 0 &&
            execute_command(command3, false, false) == 0)
          std::cout << " " << check << "CMakeLists.txt modified " << std::endl;
        else
          throw(nptool::Error("npanalysis", "Failed to modify CMakeLists.txt"));

        command = sed + "\'s/duplicate plugin:/duplicate plugin: " + *it + "/g\' ./project.yaml";
        if (execute_command(command, false, false) == 0)
          std::cout << " " << check << "Added to project.yaml " << std::endl;
        else
          throw(nptool::Error("npanalysis", "Failed to modify project.yaml"));
      }
    }

    else
      std::cout << " " << cross << *it << " is not an installed plugin. Ignoring " << std::endl;
  }
}
bool update_remote() {
  std::string url = "https://gitlab.in2p3.fr/nptool/remote-package/-/raw/main/"
    "remote_package.list";
  std::string command = "curl -s " + url + " > " + Env + "/remote_package.list ";
  auto val = system(command.c_str());
  if (val == 0)
    return true;
  else
    return false;
}