Skip to content

Commit bb6af21

Browse files
committed
Improve dependency URL parsing with regex for flexible format support
- Refactor `getDependencyGitUrl` and `getDependencyName` to use regex for matching: - Supports `user/repo` shorthand format. - Handles full GitHub/GitLab URLs with optional `www` and `.git` suffixes. - Allows generic `.git` URLs, broadening compatibility.
1 parent 8c66ef2 commit bb6af21

1 file changed

Lines changed: 38 additions & 12 deletions

File tree

‎src/Cmd/Add.cc‎

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <fstream>
1111
#include <functional>
1212
#include <optional>
13+
#include <regex>
1314
#include <string>
1415
#include <string_view>
1516
#include <toml.hpp>
@@ -66,27 +67,51 @@ handleDependency(
6667

6768
static std::string
6869
getDependencyGitUrl(const std::string_view dep) {
69-
if (dep.find("://") == std::string_view::npos) {
70-
// check if atleast in "user/repo" format
71-
if (dep.find('/') == std::string_view::npos) {
72-
logger::error("Invalid dependency: " + std::string(dep));
73-
return "";
74-
}
70+
std::regex user_repo_regex(R"(^([^/]+)/([^/]+)$)");
71+
std::regex url_regex(
72+
R"((?:https?://)?(?:www\.)?(?:github|gitlab)\.com/([^/]+/[^/]+)(?:\.git)?)"
73+
);
74+
std::regex generic_git_regex(R"((?:https?://)?.+/(.+)\.git)");
7575

76-
return "https://github.com/" + std::string(dep) + ".git";
76+
std::cmatch match;
77+
if (std::regex_match(dep.begin(), dep.end(), match, user_repo_regex)) {
78+
// Format is "user/repo"
79+
return "https://github.com/" + match[1].str() + "/" + match[2].str()
80+
+ ".git";
81+
} else if (std::regex_match(dep.begin(), dep.end(), match, url_regex)) {
82+
// Format is a valid GitHub or GitLab URL
83+
return match[0].str();
84+
} else if (std::regex_match(
85+
dep.begin(), dep.end(), match, generic_git_regex
86+
)) {
87+
// Format is a generic git URL ending with .git
88+
return match[0].str();
89+
} else {
90+
// Invalid input format
91+
return "";
7792
}
78-
return std::string(dep);
7993
}
8094

8195
static std::string
8296
getDependencyName(const std::string_view dep) {
8397
std::string name;
84-
if (dep.find("://") == std::string_view::npos) {
98+
std::regex url_regex(
99+
R"((?:https?://)?(?:www\.)?(?:github|gitlab)\.com/([^/]+)/([^/]+)(?:\.git)?)"
100+
);
101+
std::regex generic_git_regex(R"((?:https?://)?.+/(.+)\.git)");
102+
103+
std::cmatch match;
104+
if (std::regex_match(dep.begin(), dep.end(), match, url_regex)) {
105+
name = match[2].str(); // Extract only the repo name
106+
} else if (std::regex_match(
107+
dep.begin(), dep.end(), match, generic_git_regex
108+
)) {
109+
name = match[1].str();
110+
} else if (dep.find('/') != std::string_view::npos) {
111+
// Assume format is User/Repo
85112
name = dep.substr(dep.find_last_of('/') + 1);
86113
} else {
87-
name = dep.substr(
88-
dep.find_last_of('/') + 1, dep.find(".git") - dep.find_last_of('/') - 1
89-
);
114+
return "";
90115
}
91116

92117
// Remove trailing '.git' if it exists
@@ -139,6 +164,7 @@ addDependencyToManifest(
139164
const std::string depName = getDependencyName(dep);
140165

141166
if (gitUrl.empty() || depName.empty()) {
167+
logger::error("Invalid dependency: " + std::string(dep));
142168
return EXIT_FAILURE;
143169
}
144170

0 commit comments

Comments
 (0)