-
-
Notifications
You must be signed in to change notification settings - Fork 79
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allows users to add project dependencies to poac.toml from the commandline
- Loading branch information
Showing
4 changed files
with
247 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
#pragma once | ||
|
||
#include "Cmd/Add.hpp" | ||
#include "Cmd/Build.hpp" | ||
#include "Cmd/Clean.hpp" | ||
#include "Cmd/Fmt.hpp" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,235 @@ | ||
#include "Add.hpp" | ||
|
||
#include "../Logger.hpp" | ||
#include "../Manifest.hpp" | ||
#include "Common.hpp" | ||
|
||
#include <algorithm> | ||
#include <cstdlib> | ||
#include <string> | ||
#include <toml.hpp> | ||
#include <vector> | ||
|
||
static int addMain(std::span<const StringRef> args); | ||
|
||
const Subcmd ADD_CMD = | ||
Subcmd{ "add" } | ||
.setDesc("Add dependencies to poac.toml") | ||
.setArg(Arg{ "args" } | ||
.setDesc("Dependencies to add") | ||
.setRequired(true) | ||
.setVariadic(true)) | ||
.addOpt(Opt{ "--sys" }.setDesc("Use system dependency")) | ||
.addOpt(Opt{ "--version" }.setDesc( | ||
"Dependency version (Only used with system-dependencies)" | ||
)) | ||
.addOpt(Opt{ "--tag" }.setDesc("Specify a git tag").setPlaceholder("<TAG>")) | ||
.addOpt( | ||
Opt{ "--rev" }.setDesc("Specify a git revision").setPlaceholder("<REVISION>") | ||
) | ||
.addOpt( | ||
Opt{ "--branch" }.setDesc("Specify a branch of the git repository").setPlaceholder("<BRANCH_NAME>") | ||
) | ||
.setMainFn(addMain); | ||
|
||
std::optional<std::string> | ||
getNextArg( | ||
std::span<const StringRef>::iterator& itr, | ||
const std::span<const StringRef>::iterator& end | ||
) { | ||
if (++itr == end) { | ||
return std::nullopt; | ||
} | ||
return std::string(*itr); | ||
} | ||
|
||
void | ||
handleDependency(std::vector<std::string>& newDeps, const std::string& dep) { | ||
if (std::find(newDeps.begin(), newDeps.end(), dep) != newDeps.end()) { | ||
logger::warn("The dependency `" + dep + "` is already in the poac.toml"); | ||
} else { | ||
newDeps.push_back(dep); | ||
} | ||
} | ||
|
||
static int | ||
addMain(std::span<const StringRef> args) { | ||
if (args.empty()) { | ||
logger::error("No dependencies to add"); | ||
return 0; | ||
} | ||
|
||
std::vector<std::string> newDeps = {}; | ||
|
||
bool isSystemDependency = false; | ||
std::string version; // Only used with system-dependencies | ||
|
||
std::string tag; | ||
std::string rev; | ||
std::string branch; | ||
|
||
for (auto itr = args.begin(); itr != args.end(); ++itr) { | ||
if (const auto res = Cli::handleGlobalOpts(itr, args.end(), "add")) { | ||
if (res.value() == Cli::CONTINUE) { | ||
continue; | ||
} else { | ||
return res.value(); | ||
} | ||
} else if (*itr == "--sys") { | ||
isSystemDependency = true; | ||
} else if (*itr == "--version" || *itr == "-v") { | ||
if (auto nextArg = getNextArg(itr, args.end())) { | ||
version = *nextArg; | ||
} else { | ||
return ADD_CMD.missingArgumentForOpt(*--itr); | ||
} | ||
} else if (*itr == "--tag") { | ||
if (auto nextArg = getNextArg(itr, args.end())) { | ||
tag = *nextArg; | ||
} else { | ||
return ADD_CMD.missingArgumentForOpt(*--itr); | ||
} | ||
} else if (*itr == "--rev") { | ||
if (auto nextArg = getNextArg(itr, args.end())) { | ||
rev = *nextArg; | ||
} else { | ||
return ADD_CMD.missingArgumentForOpt(*--itr); | ||
} | ||
} else if (*itr == "--branch") { | ||
if (auto nextArg = getNextArg(itr, args.end())) { | ||
branch = *nextArg; | ||
} else { | ||
return ADD_CMD.missingArgumentForOpt(*--itr); | ||
} | ||
} else { | ||
handleDependency(newDeps, std::string(*itr)); | ||
} | ||
} | ||
|
||
toml::value depData = toml::table{}; | ||
|
||
if (isSystemDependency) { | ||
if (version.empty()) { | ||
logger::error("The `--version` option is required for system dependencies" | ||
); | ||
return EXIT_FAILURE; | ||
} | ||
depData["version"] = version; | ||
depData["system"] = true; | ||
} else { | ||
if (!tag.empty()) { | ||
depData["tag"] = tag; | ||
} | ||
if (!rev.empty()) { | ||
depData["rev"] = rev; | ||
} | ||
if (!branch.empty()) { | ||
depData["branch"] = branch; | ||
} | ||
} | ||
|
||
auto data = toml::parse(getManifestPath()); | ||
auto& deps = toml::find<toml::table>(data, "dependencies"); | ||
|
||
for (const auto& dep : newDeps) { | ||
|
||
if (!isSystemDependency) { | ||
const std::string gitUrl = getDependencyGitUrl(dep); | ||
const std::string depName = getDependencyName(dep); | ||
if (gitUrl.empty() || depName.empty()) { | ||
return EXIT_FAILURE; | ||
} | ||
|
||
deps[depName] = depData; | ||
deps[depName]["git"] = gitUrl; | ||
} else { | ||
deps[dep] = depData; | ||
} | ||
} | ||
|
||
std::ofstream ofs(getManifestPath()); | ||
ofs << toml::format(data); | ||
|
||
logger::info("Added", "to the poac.toml"); | ||
|
||
return 0; | ||
} | ||
|
||
std::string | ||
getDependencyGitUrl(const std::string& dep) { | ||
if (dep.find("://") == std::string::npos) { | ||
// check if atleast in "user/repo" format | ||
if (dep.find('/') == std::string::npos) { | ||
logger::error("Invalid dependency: " + dep); | ||
return ""; | ||
} | ||
|
||
return "https://github.com/" + dep + ".git"; | ||
} | ||
return dep; | ||
} | ||
|
||
std::string | ||
getDependencyName(const std::string& dep) { | ||
std::string name; | ||
if (dep.find("://") == std::string::npos) { | ||
name = dep.substr(dep.find_last_of('/') + 1); | ||
} else { | ||
name = dep.substr( | ||
dep.find_last_of('/') + 1, dep.find(".git") - dep.find_last_of('/') - 1 | ||
); | ||
} | ||
|
||
// Remove trailing '.git' if it exists | ||
if (name.rfind(".git") == name.size() - 4) { | ||
name = name.substr(0, name.size() - 4); | ||
} | ||
|
||
return name; | ||
} | ||
|
||
#ifdef POAC_TEST_OFF | ||
// getting strange linker errors for this test | ||
// test code looks fine though | ||
|
||
# include "../Rustify.hpp" | ||
|
||
namespace tests { | ||
void | ||
testGetDependencyGitUrl() { | ||
assert( | ||
getDependencyGitUrl("https://github.com/poac-dev/poac.git") | ||
== "https://github.com/poac-dev/poac.git" | ||
); | ||
assert( | ||
getDependencyGitUrl("poac-dev/poac") | ||
== "https://github.com/poac-dev/poac.git" | ||
); | ||
assert( | ||
getDependencyGitUrl("poac-dev/poac.git") | ||
== "https://github.com/poac-dev/poac.git" | ||
); | ||
assert(getDependencyGitUrl("poac-dev") == ""); | ||
assert(getDependencyGitUrl("https://github.com/poac-dev") == ""); | ||
|
||
pass(); | ||
} | ||
|
||
void | ||
testGetDependencyName() { | ||
assert(getDependencyName("poac-dev/poac") == "poac"); | ||
assert(getDependencyName("poac-dev/poac.git") == "poac"); | ||
assert(getDependencyName("https://github.com/poac-dev/poac") == "poac"); | ||
assert(getDependencyName("poac-dev") == ""); | ||
|
||
pass(); | ||
} | ||
} // namespace tests | ||
|
||
int | ||
main() { | ||
tests::testGetDependencyGitUrl(); | ||
tests::testGetDependencyName(); | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#pragma once | ||
|
||
#include "../Cli.hpp" | ||
|
||
#include <string> | ||
|
||
extern const Subcmd ADD_CMD; | ||
std::string getDependencyGitUrl(const std::string& dep); | ||
std::string getDependencyName(const std::string& dep); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters