Skip to content

Commit f249591

Browse files
committed
cufetchpm: support install multiple targets + add listing support
1 parent 0d87c43 commit f249591

File tree

7 files changed

+184
-53
lines changed

7 files changed

+184
-53
lines changed

cufetchpm/include/manifest.hpp

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
#ifndef _MANIFEST_HPP_
22
#define _MANIFEST_HPP_
33

4-
#include <optional>
54
#include <string>
65
#include <string_view>
76
#include <utility>
87
#include <vector>
98

10-
#include "libcufetch/common.hh"
119
#include "toml++/toml.hpp"
1210

1311
struct plugin_t
@@ -58,6 +56,13 @@ struct manifest_t
5856

5957
constexpr char const MANIFEST_NAME[] = "cufetchpm.toml";
6058

59+
namespace ManifestSpace {
60+
std::string getStrValue(const toml::table& tbl, const std::string_view name, const std::string_view key);
61+
std::string getStrValue(const toml::table& tbl, const std::string_view path);
62+
std::vector<std::string> getStrArrayValue(const toml::table& tbl, const std::string_view name, const std::string_view value);
63+
std::vector<std::string> getStrArrayValue(const toml::table& tbl, const std::string_view path);
64+
}
65+
6166
class CManifest
6267
{
6368
public:
@@ -81,34 +86,21 @@ class CManifest
8186
manifest_t m_repo;
8287

8388
void parse_manifest();
89+
void parse_manifest_state();
8490

8591
std::string getStrValue(const std::string_view name, const std::string_view key) const
8692
{
87-
const std::optional<std::string>& ret = m_tbl[name][key].value<std::string>();
88-
return ret.value_or(UNKNOWN);
93+
return ManifestSpace::getStrValue(m_tbl, name, key);
8994
}
9095

9196
std::string getStrValue(const std::string_view path) const
9297
{
93-
const std::optional<std::string>& ret = m_tbl.at_path(path).value<std::string>();
94-
return ret.value_or(UNKNOWN);
98+
return ManifestSpace::getStrValue(m_tbl, path);
9599
}
96100

97101
std::vector<std::string> getStrArrayValue(const std::string_view name, const std::string_view value) const
98102
{
99-
std::vector<std::string> ret;
100-
101-
// https://stackoverflow.com/a/78266628
102-
if (const toml::array* array_it = m_tbl[name][value].as_array())
103-
{
104-
array_it->for_each([&ret](auto&& el) {
105-
if (const toml::value<std::string>* str_elem = el.as_string())
106-
ret.push_back((*str_elem)->data());
107-
});
108-
109-
return ret;
110-
}
111-
return {};
103+
return ManifestSpace::getStrArrayValue(m_tbl, name, value);
112104
}
113105
};
114106

cufetchpm/include/pluginManager.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ namespace fs = std::filesystem;
1313

1414
constexpr std::string_view dependencies[] = { "git" }; // expand in the future, maybe
1515

16+
inline struct operations_t
17+
{
18+
bool install_force = false;
19+
bool list_verbose = false;
20+
std::vector<std::string> arguments;
21+
} options;
22+
1623
#define BOLD_COLOR(x) (fmt::emphasis::bold | fmt::fg(fmt::rgb(x)))
1724

1825
template <typename... Args>
@@ -38,6 +45,7 @@ class PluginManager
3845
PluginManager(StateManager&& state) : m_state(std::move(state)) {}
3946

4047
void add_repo_plugins(const std::string& repo);
48+
void build_plugins(const fs::path& working_dir);
4149
bool add_plugin(const std::string&);
4250
bool has_deps();
4351

cufetchpm/include/stateManager.hpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@ class StateManager
1717
StateManager(const StateManager&) = default;
1818
~StateManager() = default;
1919

20-
void add_new_repo(const CManifest& manifest);
21-
void add_new_plugin(const plugin_t& manifest);
22-
toml::table get_state() { return m_state; }
20+
void add_new_repo(const CManifest& manifest);
21+
void add_new_plugin(const plugin_t& manifest);
22+
std::vector<manifest_t> get_all_repos();
23+
24+
const toml::table& get_state() const
25+
{ return m_state; }
2326

2427
private:
2528
const fs::path m_path{ getConfigDir() / "plugins" / "state.toml" };

cufetchpm/src/main.cpp

Lines changed: 54 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
#include <cstdlib>
2+
#include <filesystem>
23

4+
#include "fmt/base.h"
5+
#include "fmt/ranges.h"
36
#include "libcufetch/common.hh"
47
#include "pluginManager.hpp"
58
#include "stateManager.hpp"
@@ -19,8 +22,6 @@ enum Ops
1922
LIST
2023
} op = NONE;
2124

22-
static std::vector<std::string> arguments;
23-
2425
void version()
2526
{
2627
fmt::print(
@@ -37,14 +38,14 @@ void help(int invalid_opt = false)
3738
{
3839
fmt::print(R"(Usage: cufetchpm <command> [options]
3940
Manage plugins for customfetch.
40-
NOTE: the operations must be the first argument to pass
4141
4242
Commands:
43-
install [options] <repo> Install a new plugin repository. Takes as an argument the git url to be cloned.
43+
install [options] <repo/path>... Install one or more plugin sources from a Git repo or local path.
44+
help <command> Show help for a specific command.
4445
4546
Global options:
46-
-h, --help Print this help menu.
47-
-V, --version Print version and other infos about the build.
47+
-h, --help Show this help message.
48+
-V, --version Show version and build information.
4849
4950
)");
5051

@@ -53,11 +54,17 @@ Global options:
5354

5455
void help_install(int invalid_opt = false)
5556
{
56-
fmt::print(R"(Usage: cufetchpm install [options] <repo>
57+
fmt::print(R"(Usage: cufetchpm install [options] <repo/path>...
58+
59+
Install one or more plugin sources. If a given argument exists on disk,
60+
it is treated as a local directory. Otherwise, it is treated as a Git
61+
repository URL and will be cloned.
62+
63+
All plugins found within the source will be installed.
5764
5865
Options:
59-
-f, --force Force installation
60-
-h, --help Show help for install
66+
-f, --force Force installation, even if already installed.
67+
-h, --help Show help for this command.
6168
)");
6269

6370
std::exit(invalid_opt);
@@ -66,19 +73,18 @@ void help_install(int invalid_opt = false)
6673
void help_list(int invalid_opt = false)
6774
{
6875
fmt::print(R"(Usage: cufetchpm list [options]
76+
List all installed plugins.
6977
7078
Options:
71-
-v, --verbose Show detailed info
72-
-h, --help Show help for list
79+
-v, --verbose Show detailed plugin information.
80+
-h, --help Show help for this command.
7381
)");
7482

7583
std::exit(invalid_opt);
7684
}
7785

7886
bool parse_install_args(int argc, char* argv[])
7987
{
80-
bool force = false;
81-
8288
// clang-format off
8389
const struct option long_opts[] = {
8490
{"force", no_argument, nullptr, 'f'},
@@ -92,25 +98,23 @@ bool parse_install_args(int argc, char* argv[])
9298
{
9399
switch (opt)
94100
{
95-
case 'f': force = true; break;
101+
case 'f': options.install_force = true; break;
96102
case 'h': help_install(EXIT_SUCCESS); break;
97103
case '?': help_install(EXIT_FAILURE); break;
98104
}
99105
}
100106

101107
for (int i = optind; i < argc; ++i)
102-
arguments.emplace_back(argv[i]);
108+
options.arguments.emplace_back(argv[i]);
103109

104-
if (arguments.empty())
105-
die("install: no repositories given");
110+
if (options.arguments.empty())
111+
die("install: no repositories/paths given");
106112

107113
return true;
108114
}
109115

110116
bool parse_list_args(int argc, char* argv[])
111117
{
112-
bool verbose = false;
113-
114118
// clang-format off
115119
const struct option long_opts[] = {
116120
{"verbose", no_argument, nullptr, 'v'},
@@ -124,7 +128,7 @@ bool parse_list_args(int argc, char* argv[])
124128
{
125129
switch (opt)
126130
{
127-
case 'v': verbose = true; break;
131+
case 'v': options.list_verbose = true; break;
128132
case 'h': help_list(EXIT_SUCCESS); break;
129133
case '?': help_list(EXIT_FAILURE); break;
130134
}
@@ -206,15 +210,42 @@ int main(int argc, char* argv[])
206210
return -1;
207211

208212
fs::create_directories({ getHomeCacheDir() / "cufetchpm" / "plugins" });
213+
fs::create_directories({ getConfigDir() / "plugins" });
214+
StateManager state;
209215
switch (op)
210216
{
211217
case INSTALL:
212218
{
213-
if (arguments.size() < 1)
219+
if (options.arguments.size() < 1)
214220
die("Please provide a singular git url repository");
215-
StateManager state;
216221
PluginManager plugin_manager(std::move(state));
217-
plugin_manager.add_repo_plugins(arguments[0]);
222+
for (const std::string& arg : options.arguments)
223+
{
224+
if (arg.find("://") == arg.npos && fs::exists(arg))
225+
plugin_manager.build_plugins(arg);
226+
else
227+
plugin_manager.add_repo_plugins(arg);
228+
}
229+
break;
230+
}
231+
case LIST:
232+
{
233+
for (const manifest_t& manifest : state.get_all_repos())
234+
{
235+
fmt::println("\033[1;32mRepository:\033[0m {}", manifest.name);
236+
fmt::println("\033[1;33mURL:\033[0m {}", manifest.url);
237+
fmt::println("\033[1;34mPlugins:");
238+
for (const plugin_t& plugin : manifest.plugins)
239+
{
240+
fmt::println("\033[1;34m - {}\033[0m", plugin.name);
241+
fmt::println("\t\033[1;35mDescription:\033[0m {}", plugin.description);
242+
fmt::println("\t\033[1;36mAuthor(s):\033[0m {}", fmt::join(plugin.authors, ", "));
243+
fmt::println("\t\033[1;38;2;220;220;220mLicense(s):\033[0m {}", fmt::join(plugin.licenses, ", "));
244+
fmt::println("\t\033[1;38;2;144;238;144mPrefixe(s):\033[0m {}", fmt::join(plugin.prefixes, ", "));
245+
fmt::print("\n");
246+
}
247+
fmt::print("\033[0m");
248+
}
218249
break;
219250
}
220251
default: warn("uh?");

cufetchpm/src/manifest.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,52 @@ static bool is_valid_name(const std::string_view n)
1313
[](const unsigned char c) { return (isalnum(c) || c == '-' || c == '_' || c == '='); });
1414
}
1515

16+
std::string ManifestSpace::getStrValue(const toml::table& tbl, const std::string_view name, const std::string_view key)
17+
{
18+
const std::optional<std::string>& ret = tbl[name][key].value<std::string>();
19+
return ret.value_or(UNKNOWN);
20+
}
21+
22+
std::string ManifestSpace::getStrValue(const toml::table& tbl, const std::string_view path)
23+
{
24+
const std::optional<std::string>& ret = tbl.at_path(path).value<std::string>();
25+
return ret.value_or(UNKNOWN);
26+
}
27+
28+
std::vector<std::string> ManifestSpace::getStrArrayValue(const toml::table& tbl, const std::string_view path)
29+
{
30+
std::vector<std::string> ret;
31+
32+
// https://stackoverflow.com/a/78266628
33+
if (const toml::array* array_it = tbl.at_path(path).as_array())
34+
{
35+
array_it->for_each([&ret](auto&& el) {
36+
if (const toml::value<std::string>* str_elem = el.as_string())
37+
ret.push_back((*str_elem)->data());
38+
});
39+
40+
return ret;
41+
}
42+
return {};
43+
}
44+
45+
std::vector<std::string> ManifestSpace::getStrArrayValue(const toml::table& tbl, const std::string_view name, const std::string_view value)
46+
{
47+
std::vector<std::string> ret;
48+
49+
// https://stackoverflow.com/a/78266628
50+
if (const toml::array* array_it = tbl[name][value].as_array())
51+
{
52+
array_it->for_each([&ret](auto&& el) {
53+
if (const toml::value<std::string>* str_elem = el.as_string())
54+
ret.push_back((*str_elem)->data());
55+
});
56+
57+
return ret;
58+
}
59+
return {};
60+
}
61+
1662
CManifest::CManifest(const std::string_view path)
1763
{
1864
try

cufetchpm/src/pluginManager.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,11 @@ void PluginManager::add_repo_plugins(const std::string& repo)
5252
die("Failed to clone at directory '{}'", working_dir.string());
5353
}
5454
success("Successfully cloned. Changing current directory to '{}'", working_dir.string());
55+
build_plugins(working_dir);
56+
}
5557

58+
void PluginManager::build_plugins(const fs::path& working_dir)
59+
{
5660
// cd to the working directory and parse its manifest
5761
fs::current_path(working_dir);
5862
CManifest manifest(MANIFEST_NAME);
@@ -84,7 +88,7 @@ void PluginManager::add_repo_plugins(const std::string& repo)
8488
if (Process(bs, "").get_exit_status() != 0)
8589
{
8690
fs::remove_all(working_dir);
87-
die("Failed to build plugin '{}' from '{}'", plugin.name, repo);
91+
die("Failed to build plugin '{}'", plugin.name);
8892
}
8993
}
9094
success("Successfully built '{}' into '{}'", plugin.name, plugin.output_dir);

0 commit comments

Comments
 (0)