Skip to content

Commit

Permalink
added basic package search
Browse files Browse the repository at this point in the history
  • Loading branch information
DeaSTL committed Oct 28, 2023
1 parent deaa337 commit c8822a1
Show file tree
Hide file tree
Showing 7 changed files with 225 additions and 36 deletions.
2 changes: 1 addition & 1 deletion src/Command/Command.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ namespace Command {
* adds a dependency to the config.toml
* @returns bool -> finished successfully
*/
bool addDependency(std::shared_ptr<Context> &ctx, cxxopts::ParseResult &args);
bool addDependency(std::shared_ptr<Context> ctx, cxxopts::ParseResult &args);
/*
* Generates cmake file for project based on the current project context
* @returns bool -> finished successfully
Expand Down
179 changes: 154 additions & 25 deletions src/Command/CommandAdd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@
#include <iostream>
#include <nlohmann/json.hpp>
#include <string>
#include "../Utils/General.hpp"
#include <cmath>

namespace Command {
using nlohmann::json;
bool add(std::shared_ptr<Context> &ctx, cxxopts::ParseResult &args) {
args.count("subcommand");
if (args.count("subcommand") != 0) {
Expand Down Expand Up @@ -55,34 +58,160 @@ namespace Command {
}
}

bool addDependency(std::shared_ptr<Context> &ctx, cxxopts::ParseResult &args) {
std::cout << "addDependency" << std::endl;
if (args.count("help")) {
std::cout << "Usage: add dep [options] name url branch" << std::endl;
}
nlohmann::json json = fetch(
"https://raw.githubusercontent.com/cmaker-dev/index/main/index.json");
for (auto package : json) {
if (package["Name"] == args["args"].as<std::vector<std::string>>()[0]) {
nlohmann::json package_data =
fetch("https://raw.githubusercontent.com/cmaker-dev/index/main/" +
static_cast<std::string>(package["Name"]) + "/info.json");
dependency dependency_new = {
.name = static_cast<std::string>(package_data["Name"]),
.url = static_cast<std::string>(package_data["Homepage"]),
.version = static_cast<std::string>(package_data["Tag"]),
.target_link = static_cast<std::string>(package_data["Link"])};

if (std::any_of(ctx->dependencies.begin(), ctx->dependencies.end(),
[&dependency_new](dependency &dep) {
return dep.name == dependency_new.name;
})) {
std::cout << "Dependency already exists not adding" << std::endl;
} else {
ctx->dependencies.push_back(dependency_new);
std::string downloadIndex() {
std::cout << "Downloading index.json" << std::endl;
cpr::Response r = cpr::Get(cpr::Url{"https://github.com/cmaker-dev/index/releases/latest/download/index.json"});
std::cout << r.status_code << std::endl;
return r.text;
}
typedef struct packageResult {
std::string name;
std::string url;
std::string version;
int score;
} packageResult;
std::vector<packageResult> calculatePackageScores(std::vector<std::string> queryTokens){
std::vector<packageResult> results;
std::string index = downloadIndex();
json rawIndex = json::parse(index);
int lengthDiffAbs = 0;
for(std::string query: queryTokens){
for(json package: rawIndex){
//TODO: add description that can be searched
results.push_back({
.name = package["name"],
.url = package["git"],
.score = 0
});
//if it is an exact match
if(results.back().name == query){
results.back().score += 100;
break;
}
//Check if the query is in the package name
if(results.back().name.find(query) != std::string::npos){
results.back().score += 50;
}

lengthDiffAbs = std::abs((int)results.back().name.length() - (int)query.length());
if(results.back().score > 10){
results.back().score -= lengthDiffAbs;
}
}
}
std::sort(results.begin(), results.end(), [](packageResult a, packageResult b){
return a.score > b.score;
});
std::vector<packageResult> resultsUnique;

for(packageResult result: results){
if(std::any_of(resultsUnique.begin(), resultsUnique.end(), [&result](packageResult &r){
r.score += result.score;
return r.name == result.name;
})){
continue;
}
resultsUnique.push_back(result);
}
return resultsUnique;
}
std::vector<packageResult> searchPackage(std::string query){
std::cout << "Searching for package" << std::endl;

std::vector<std::string> queryTokens = Utils::split(query, ' ');

std::vector<packageResult> results = calculatePackageScores(queryTokens);


std::cout << "Results:" << std::endl;
for(int i = results.size();i > -1; i--){
if(results[i].score > 10){
//Adjusting the indexes for the normies
std::cout << "[" << i << "]" << results[i].name << " - (" << results[i].url << ")" << std::endl;
}
}

return results;
}


bool checkForOverlappingDependencies(std::shared_ptr<Context> ctx, std::string name){
if(ctx->dependencies.size() == 0){
return false;
}
for(dependency dep: ctx->dependencies){
if(dep.name == name){
return true;
}
}
}

bool addDependency(std::shared_ptr<Context> ctx, cxxopts::ParseResult &args) {
for(auto arg: args.arguments()){
std::cout << arg.key() << std::endl;
}
if (args.count("subcommand") > 2) {
std::cout << "Usage: add dep [options] name url branch" << std::endl;
return false;
}else{

std::vector<packageResult> searchResults = searchPackage(args["args"].as<std::vector<std::string>>()[0]);
if(searchResults.size() == 0){
std::cout << "No results found" << std::endl;
return false;
}
std::cout << "Select a package to install: ";
std::string input;
std::cin >> input;
int index = std::stoi(input);

std::cout << "Installing " << searchResults[index].name << std::endl;

if(checkForOverlappingDependencies(ctx, searchResults[index].name)){
std::cout << "Package already installed" << std::endl;
return false;
}

std::cout << "Adding dependency to config.toml" << std::endl;
ctx->dependencies.push_back({

.name = searchResults[index].name,
.url = searchResults[index].url,
.version = "origin/main",
//TODO: Change target link to be the actual link
.target_link = searchResults[index].name

});
std::cout << "Writing config.toml" << std::endl;
Generators::ConfigToml::writeConfig(ctx);

return true;
}



// nlohmann::json json = fetch(
// "https://github.com/cmaker-dev/index/releases/latest/download/index.json");


// for (nlohmann::json package : json) {
// if (package["Name"] == args["args"].as<std::vector<std::string>>()[0]) {
// dependency dependency_new = {
// .name = static_cast<std::string>(package_data["Name"]),
// .url = static_cast<std::string>(package_data["Homepage"]),
// .version = static_cast<std::string>(package_data["Tag"]),
// .target_link = static_cast<std::string>(package_data["Link"])};
//
// if (std::any_of(ctx->dependencies.begin(), ctx->dependencies.end(),
// [&dependency_new](dependency &dep) {
// return dep.name == dependency_new.name;
// })) {
// std::cout << "Dependency already exists not adding" << std::endl;
// } else {
// ctx->dependencies.push_back(dependency_new);
// }
// }
// }
std::cout << ctx->dependencies.size() << std::endl;
Generators::ConfigToml::writeConfig(ctx);
Generators::CMakeList::create(ctx);
Expand Down
20 changes: 10 additions & 10 deletions src/Command/CommandGeneral.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,21 @@ namespace Command {
#endif

auto data = toml::parse_file((ctx->project_path / file_name).string());
ctx->project_name = data["project"]["project_name"].value_or("no name");
ctx->project_name = data["project"]["project_name"].value_or("");
for (auto &author : *data["project"]["authors"].as_array()) {
ctx->authors.push_back(author.value_or("no author"));
ctx->authors.push_back(author.value_or(""));
}
ctx->src_dir = data["project"]["src_dir"].value_or("no src_dir");
ctx->build_dir = data["project"]["build_dir"].value_or("no build_dir");
ctx->compiler = data["project"]["compiler"].value_or("no compiler");
ctx->src_dir = data["project"]["src_dir"].value_or("");
ctx->build_dir = data["project"]["build_dir"].value_or("");
ctx->compiler = data["project"]["compiler"].value_or("");
ctx->cmake_version = data["project"]["cmake_version"].value_or("");
ctx->git = data["project"]["git"].value_or("no git");
ctx->lang = data["project"]["lang"].value_or("no lang");
ctx->git = data["project"]["git"].value_or("");
ctx->lang = data["project"]["lang"].value_or("");
ctx->include_dir =
data["project"]["include_dir"].value_or("no include_dir");
data["project"]["include_dir"].value_or("");
ctx->lang_version =
data["project"]["lang_version"].value_or("no langversion");
ctx->project_version = data["project"]["project_version"].value_or("0.0.1");
data["project"]["lang_version"].value_or("");
ctx->project_version = data["project"]["project_version"].value_or("");
if (data.at_path("dependencies").is_table()) {
for (auto &dep : *data["dependencies"].as_table()) {

Expand Down
35 changes: 35 additions & 0 deletions src/Command/CommandSearchPackage.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "Command.hpp"
#include <curl/curl.h>
#include <curl/easy.h>
#include <nlohmann/json.hpp>



namespace Command {
// const std::string RepoIndex = "https://raw.githubusercontent.com/cmaker-dev/index/main/index.json";
// void writeCallback(char* ptr, size_t size, size_t nmemb, std::string* data) {
// data->append(ptr, size * nmemb);
// }
// void SearchPackage(){
// curl_easy_init();
// std::shared_ptr<CURL> curl(curl_easy_init(), curl_easy_cleanup);
//
// curl_easy_setopt(curl.get(), CURLOPT_URL, RepoIndex.c_str());
//
// std::string response;
//
// curl_easy_setopt(curl.get(), CURLOPT_WRITEFUNCTION, writeCallback);
// curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA, &response);
//
// curl_easy_perform(curl.get());
//
// nlohmann::json j = nlohmann::json::parse(response);
//
// std::cout << j.dump(4) << std::endl;
//
//
//
// }


}
19 changes: 19 additions & 0 deletions src/Utils/General.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,28 @@
#include <filesystem>
#include <iostream>
#include <vector>
namespace Utils{
std::string getFolderName(){
std::string directory_name = std::filesystem::current_path();
directory_name = directory_name.substr(directory_name.find_last_of("/\\") + 1);
return directory_name;
}
std::vector<std::string> split(std::string str, char delimiter){
std::vector<std::string> result;

std::string word = "";

for (char x : str) {
if (x == delimiter) {
result.push_back(word);
word = "";
} else {
word = word + x;
}
}
if(result.size() == 0){
result.push_back(word);
}
return result;
}
}
2 changes: 2 additions & 0 deletions src/Utils/General.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once
#include <string>
#include <vector>
namespace Utils {
std::string getFolderName();
std::vector<std::string> split(std::string str, char delimiter);
}
4 changes: 4 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ int main(int argc, char **argv) {
else if (command == "add"){
Command::loadPackageToml(ctx);
Command::add(ctx, result);
}else{
std::cout << "Invalid command try one of these" << ENDL;
Command::help();

}
#endif
}

0 comments on commit c8822a1

Please sign in to comment.