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
|
true
|
||||||
} else if let Some(gitlab_parts) = util::gitlab::extract_gitlab_url_parts(git_repo_url) {
|
} else if let Some(gitlab_parts) = util::gitlab::extract_gitlab_url_parts(git_repo_url) {
|
||||||
panic!("GitLab is not supported yet!");
|
if let Some(repo_scheme) =
|
||||||
todo!();
|
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
|
true
|
||||||
} else {
|
} 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
|
// available to non-authenticated requests), so we check if a "git ls-remote" command
|
||||||
// is able to access it.
|
// is able to access it.
|
||||||
if matches_known_hosts && !util::git::is_private_repo(git_repo_url) {
|
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 hub;
|
||||||
pub(crate) mod git;
|
pub(crate) mod git;
|
||||||
pub(crate) mod github;
|
pub(crate) mod github;
|
||||||
|
pub(crate) mod gitlab;
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct PackageSpecifier {
|
pub struct PackageSpecifier {
|
||||||
|
|
|
@ -59,6 +59,14 @@ pub fn resolve_repo_scheme(parts: GitHubParts, force_branch: Option<&str>) -> Re
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
} else {
|
} 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")? {
|
if check_repo_with_branch(&parts, "master")? {
|
||||||
return Ok(Some(ResolvedRepoScheme {
|
return Ok(Some(ResolvedRepoScheme {
|
||||||
author: parts.author,
|
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)
|
Ok(None)
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
use anyhow::Result;
|
||||||
|
use reqwest::StatusCode;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref GITLAB_REGEX: Regex = Regex::new(r"(https://gitlab.com/|git@gitlab.com:)(?P<author>.*?)/(?P<name>.*?)(/|\.|$)").unwrap();
|
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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user