feat(package): implement gitlab package provider
This commit is contained in:
parent
db77e9617a
commit
d86c6f7c46
|
@ -51,8 +51,15 @@ pub fn get_provider(package: &PackageSpecifier, runtime_dir: &Path, options: &Pr
|
|||
|
||||
true
|
||||
} else if let Some(gitlab_parts) = util::gitlab::extract_gitlab_url_parts(git_repo_url) {
|
||||
panic!("GitLab is not supported yet!");
|
||||
todo!();
|
||||
if let Some(repo_scheme) =
|
||||
util::gitlab::resolve_repo_scheme(gitlab_parts, package.git_branch.as_deref())?
|
||||
{
|
||||
return Ok(Box::new(provider::gitlab::GitLabPackageProvider::new(
|
||||
repo_scheme.author,
|
||||
repo_scheme.name,
|
||||
repo_scheme.branch,
|
||||
)));
|
||||
}
|
||||
|
||||
true
|
||||
} else {
|
||||
|
@ -64,7 +71,7 @@ pub fn get_provider(package: &PackageSpecifier, runtime_dir: &Path, options: &Pr
|
|||
// available to non-authenticated requests), so we check if a "git ls-remote" command
|
||||
// is able to access it.
|
||||
if matches_known_hosts && !util::git::is_private_repo(git_repo_url) {
|
||||
bail!("could not access repository: {}, make sure it exists and that you have the necessary access rights.");
|
||||
bail!("could not access repository: {}, make sure it exists and that you have the necessary access rights.", git_repo_url);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
68
espanso-package/src/provider/gitlab.rs
Normal file
68
espanso-package/src/provider/gitlab.rs
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* This file is part of espanso.
|
||||
*
|
||||
* Copyright (C) 2019-2021 Federico Terzi
|
||||
*
|
||||
* espanso is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* espanso is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use crate::{
|
||||
package::DefaultPackage, resolver::resolve_package, Package, PackageSpecifier,
|
||||
};
|
||||
use anyhow::{Result};
|
||||
use super::PackageProvider;
|
||||
|
||||
pub struct GitLabPackageProvider {
|
||||
repo_author: String,
|
||||
repo_name: String,
|
||||
repo_branch: String,
|
||||
}
|
||||
|
||||
impl GitLabPackageProvider {
|
||||
pub fn new(repo_author: String, repo_name: String, repo_branch: String) -> Self {
|
||||
Self {
|
||||
repo_author,
|
||||
repo_name,
|
||||
repo_branch,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PackageProvider for GitLabPackageProvider {
|
||||
fn name(&self) -> String {
|
||||
"gitlab".to_string()
|
||||
}
|
||||
|
||||
fn download(&self, package: &PackageSpecifier) -> Result<Box<dyn Package>> {
|
||||
let download_url = format!(
|
||||
"https://gitlab.com/{}/{}/-/archive/{}/{}-{}.zip",
|
||||
&self.repo_author, &self.repo_name, &self.repo_branch, &self.repo_name, &self.repo_branch
|
||||
);
|
||||
|
||||
let temp_dir = tempdir::TempDir::new("espanso-package-download")?;
|
||||
|
||||
crate::util::download::download_and_extract_zip(&download_url, temp_dir.path())?;
|
||||
|
||||
let resolved_package =
|
||||
resolve_package(temp_dir.path(), &package.name, package.version.as_deref())?;
|
||||
|
||||
let package = DefaultPackage::new(
|
||||
resolved_package.manifest,
|
||||
temp_dir,
|
||||
resolved_package.base_dir,
|
||||
);
|
||||
|
||||
Ok(Box::new(package))
|
||||
}
|
||||
}
|
|
@ -24,6 +24,7 @@ use crate::Package;
|
|||
pub(crate) mod hub;
|
||||
pub(crate) mod git;
|
||||
pub(crate) mod github;
|
||||
pub(crate) mod gitlab;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct PackageSpecifier {
|
||||
|
|
|
@ -59,6 +59,14 @@ pub fn resolve_repo_scheme(parts: GitHubParts, force_branch: Option<&str>) -> Re
|
|||
}))
|
||||
}
|
||||
} else {
|
||||
if check_repo_with_branch(&parts, "main")? {
|
||||
return Ok(Some(ResolvedRepoScheme {
|
||||
author: parts.author,
|
||||
name: parts.name,
|
||||
branch: "main".to_string(),
|
||||
}));
|
||||
}
|
||||
|
||||
if check_repo_with_branch(&parts, "master")? {
|
||||
return Ok(Some(ResolvedRepoScheme {
|
||||
author: parts.author,
|
||||
|
@ -67,13 +75,6 @@ pub fn resolve_repo_scheme(parts: GitHubParts, force_branch: Option<&str>) -> Re
|
|||
}));
|
||||
}
|
||||
|
||||
if check_repo_with_branch(&parts, "main")? {
|
||||
return Ok(Some(ResolvedRepoScheme {
|
||||
author: parts.author,
|
||||
name: parts.name,
|
||||
branch: "main".to_string(),
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
use lazy_static::lazy_static;
|
||||
use regex::Regex;
|
||||
use anyhow::Result;
|
||||
use reqwest::StatusCode;
|
||||
|
||||
lazy_static! {
|
||||
static ref GITLAB_REGEX: Regex = Regex::new(r"(https://gitlab.com/|git@gitlab.com:)(?P<author>.*?)/(?P<name>.*?)(/|\.|$)").unwrap();
|
||||
|
@ -41,6 +43,55 @@ pub fn extract_gitlab_url_parts(url: &str) -> Option<GitLabParts> {
|
|||
})
|
||||
}
|
||||
|
||||
pub struct ResolvedRepoScheme {
|
||||
pub author: String,
|
||||
pub name: String,
|
||||
pub branch: String,
|
||||
}
|
||||
|
||||
pub fn resolve_repo_scheme(parts: GitLabParts, force_branch: Option<&str>) -> Result<Option<ResolvedRepoScheme>> {
|
||||
if let Some(force_branch) = force_branch {
|
||||
if check_repo_with_branch(&parts, force_branch)? {
|
||||
return Ok(Some(ResolvedRepoScheme {
|
||||
author: parts.author,
|
||||
name: parts.name,
|
||||
branch: force_branch.to_string(),
|
||||
}))
|
||||
}
|
||||
} else {
|
||||
if check_repo_with_branch(&parts, "main")? {
|
||||
return Ok(Some(ResolvedRepoScheme {
|
||||
author: parts.author,
|
||||
name: parts.name,
|
||||
branch: "main".to_string(),
|
||||
}));
|
||||
}
|
||||
|
||||
if check_repo_with_branch(&parts, "master")? {
|
||||
return Ok(Some(ResolvedRepoScheme {
|
||||
author: parts.author,
|
||||
name: parts.name,
|
||||
branch: "master".to_string(),
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
pub fn check_repo_with_branch(parts: &GitLabParts, branch: &str) -> Result<bool> {
|
||||
let client = reqwest::blocking::Client::new();
|
||||
|
||||
let url = generate_gitlab_download_url(parts, branch);
|
||||
let response = client.head(url).send()?;
|
||||
|
||||
Ok(response.status() == StatusCode::OK)
|
||||
}
|
||||
|
||||
fn generate_gitlab_download_url(parts: &GitLabParts, branch: &str) -> String {
|
||||
format!("https://gitlab.com/{}/{}/-/archive/{}/{}-{}.zip", parts.author, parts.name, branch, parts.name, branch)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
Loading…
Reference in New Issue
Block a user