reapack

Package manager for REAPER
Log | Files | Refs | Submodules | README | LICENSE

package.cpp (4038B)


      1 /* ReaPack: Package manager for REAPER
      2  * Copyright (C) 2015-2025  Christian Fillion
      3  *
      4  * This program is free software: you can redistribute it and/or modify
      5  * it under the terms of the GNU Lesser General Public License as published by
      6  * the Free Software Foundation, either version 3 of the License, or
      7  * (at your option) any later version.
      8  *
      9  * This program is distributed in the hope that it will be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12  * GNU Lesser General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU Lesser General Public License
     15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
     16  */
     17 
     18 #include "package.hpp"
     19 
     20 #include "errors.hpp"
     21 #include "index.hpp"
     22 
     23 #include <algorithm>
     24 #include <boost/range/adaptor/reversed.hpp>
     25 
     26 Package::Type Package::getType(const char *type)
     27 {
     28   constexpr std::pair<const char *, Type> map[] {
     29     {"script",        ScriptType},
     30     {"extension",     ExtensionType},
     31     {"effect",        EffectType},
     32     {"data",          DataType},
     33     {"theme",         ThemeType},
     34     {"langpack",      LangPackType},
     35     {"webinterface",  WebInterfaceType},
     36     {"projecttpl",    ProjectTemplateType},
     37     {"tracktpl",      TrackTemplateType},
     38     {"midinotenames", MIDINoteNamesType},
     39     {"autoitem",      AutomationItemType},
     40   };
     41 
     42   for(auto &[key, value] : map) {
     43     if(!strcmp(type, key))
     44       return value;
     45   }
     46 
     47   return UnknownType;
     48 }
     49 
     50 const char *Package::displayType(const Type type)
     51 {
     52   switch(type) {
     53   case UnknownType:
     54     break;
     55   case ScriptType:
     56     return "Script";
     57   case ExtensionType:
     58     return "Extension";
     59   case EffectType:
     60     return "Effect";
     61   case DataType:
     62     return "Data";
     63   case ThemeType:
     64     return "Theme";
     65   case LangPackType:
     66     return "Language Pack";
     67   case WebInterfaceType:
     68     return "Web Interface";
     69   case ProjectTemplateType:
     70     return "Project Template";
     71   case TrackTemplateType:
     72     return "Track Template";
     73   case MIDINoteNamesType:
     74     return "MIDI Note Names";
     75   case AutomationItemType:
     76     return "Automation Item";
     77   }
     78 
     79   return "Unknown";
     80 }
     81 
     82 const std::string &Package::displayName(const std::string &name, const std::string &desc)
     83 {
     84   return desc.empty() ? name : desc;
     85 }
     86 
     87 Package::Package(const Type type, const std::string &name, const Category *cat)
     88   : m_category(cat), m_type(type), m_name(name)
     89 {
     90   if(m_name.empty())
     91     throw reapack_error("empty package name");
     92   else if(m_name.find_first_of("/\\") != std::string::npos) {
     93     throw reapack_error(
     94       String::format("invalid package name '%s'", m_name.c_str()));
     95   }
     96 }
     97 
     98 Package::~Package()
     99 {
    100   for(const Version *ver : m_versions)
    101     delete ver;
    102 }
    103 
    104 std::string Package::fullName() const
    105 {
    106   return m_category ? m_category->fullName() + "/" + displayName() : displayName();
    107 }
    108 
    109 bool Package::addVersion(const Version *ver)
    110 {
    111   if(ver->package() != this)
    112     throw reapack_error("version belongs to another package");
    113   else if(ver->sources().empty())
    114     return false;
    115   else if(m_versions.count(ver)) {
    116     throw reapack_error(String::format("duplicate version '%s'",
    117       ver->fullName().c_str()));
    118   }
    119 
    120   m_versions.insert(ver);
    121 
    122   return true;
    123 }
    124 
    125 const Version *Package::version(const size_t index) const
    126 {
    127   auto it = m_versions.begin();
    128   advance(it, index);
    129 
    130   return *it;
    131 }
    132 
    133 const Version *Package::lastVersion(const bool pres, const VersionName &from) const
    134 {
    135   if(m_versions.empty())
    136     return nullptr;
    137 
    138   for(const Version *ver : m_versions | boost::adaptors::reversed) {
    139     if(ver->name() < from)
    140       break;
    141     else if(ver->name().isStable() || pres)
    142       return ver;
    143   }
    144 
    145   return from.isStable() ? nullptr : *m_versions.rbegin();
    146 }
    147 
    148 const Version *Package::findVersion(const VersionName &ver) const
    149 {
    150   const auto &it = find_if(m_versions.begin(), m_versions.end(),
    151     [=] (const Version *cur) { return cur->name() == ver; });
    152 
    153   if(it == m_versions.end())
    154     return nullptr;
    155   else
    156     return *it;
    157 }