Commit 4eec6b02 authored by darlaam's avatar darlaam
Browse files

Add some creates methods

Removing blank line in gitignore
parent 8306233b
......@@ -230,6 +230,14 @@ enum_serialize!(MergeRequestStateFilter -> "state",
Merged => "merged",
);
/// Should a certificate be validated in tls connections.
/// The Insecure option is used for self-signed certificates.
#[derive(Debug, Clone)]
enum CertPolicy {
Default,
Insecure,
}
impl Gitlab {
/// Create a new Gitlab API representation.
///
......@@ -240,7 +248,12 @@ impl Gitlab {
H: AsRef<str>,
T: ToString,
{
Self::new_impl("https", host.as_ref(), Token::Private(token.to_string()))
Self::new_impl(
"https",
host.as_ref(),
Token::Private(token.to_string()),
CertPolicy::Default,
)
}
/// Create a new non-SSL Gitlab API representation.
......@@ -251,7 +264,12 @@ impl Gitlab {
H: AsRef<str>,
T: ToString,
{
Self::new_impl("http", host.as_ref(), Token::Private(token.to_string()))
Self::new_impl(
"http",
host.as_ref(),
Token::Private(token.to_string()),
CertPolicy::Insecure,
)
}
/// Create a new Gitlab API representation.
......@@ -263,7 +281,12 @@ impl Gitlab {
H: AsRef<str>,
T: ToString,
{
Self::new_impl("https", host.as_ref(), Token::OAuth2(token.to_string()))
Self::new_impl(
"https",
host.as_ref(),
Token::OAuth2(token.to_string()),
CertPolicy::Default,
)
}
/// Create a new non-SSL Gitlab API representation.
......@@ -275,15 +298,34 @@ impl Gitlab {
H: AsRef<str>,
T: ToString,
{
Self::new_impl("http", host.as_ref(), Token::OAuth2(token.to_string()))
Self::new_impl(
"http",
host.as_ref(),
Token::OAuth2(token.to_string()),
CertPolicy::Default,
)
}
/// Internal method to create a new Gitlab client.
fn new_impl(protocol: &str, host: &str, token: Token) -> GitlabResult<Self> {
fn new_impl(
protocol: &str,
host: &str,
token: Token,
cert_validation: CertPolicy,
) -> GitlabResult<Self> {
let base_url = Url::parse(&format!("{}://{}/api/v4/", protocol, host))?;
let client = match cert_validation {
CertPolicy::Insecure => {
Client::builder()
.danger_accept_invalid_certs(true)
.build()?
},
CertPolicy::Default => Client::new(),
};
let api = Gitlab {
client: Client::new(),
client,
base_url,
token,
};
......@@ -344,6 +386,89 @@ impl Gitlab {
.ok_or_else(|| GitlabError::no_such_user(name.as_ref()))
}
/// Create a project (Needs admin access)
pub fn create_project<N: AsRef<str>, P: AsRef<str>>(
&self,
name: N,
path: Option<P>,
namespace_id: GroupId,
) -> GitlabResult<Project> {
let url = "projects";
let path = match path.as_ref() {
None => name.as_ref(),
Some(s) => s.as_ref(),
};
self.post_with_param(
url,
&[
("name", name.as_ref()),
("path", path),
("namespace_id", namespace_id.to_string().as_str()),
],
)
}
/// Create a new file in repository
pub fn create_file<F, B, C, M>(
&self,
project: ProjectId,
file_path: F,
branch: B,
content: C,
commit_message: M,
) -> GitlabResult<RepoFile>
where
F: AsRef<str>,
B: AsRef<str>,
C: AsRef<str>,
M: AsRef<str>,
{
let url = format!(
"projects/{}/repository/files/{}",
project,
file_path.as_ref()
);
self.post_with_param(
url,
&[
("branch", branch.as_ref()),
("content", content.as_ref()),
("commit_message", commit_message.as_ref()),
],
)
}
/// Set project description
pub fn set_project_description<T: AsRef<str>>(
&self,
project: ProjectId,
description: T,
) -> GitlabResult<Project> {
let url = format!("projects/{}", project);
self.put_with_param(url, &[("description", description.as_ref())])
}
/// Set project default branch
pub fn set_project_default_branch<T: AsRef<str>>(
&self,
project: ProjectId,
branch: T,
) -> GitlabResult<Project> {
let url = format!("projects/{}", project);
self.put_with_param(url, &[("default_branch", branch.as_ref())])
}
/// Set project features access level
pub fn set_project_feature_access_level(
&self,
project: ProjectId,
feature: ProjectFeatures,
) -> GitlabResult<Project> {
let url = format!("projects/{}", project);
self.put_with_param(url, &[(feature.name(), feature.access_level())])
}
/// Get all accessible projects.
pub fn projects<I, K, V>(&self, params: I) -> GitlabResult<Vec<Project>>
where
......@@ -424,6 +549,30 @@ impl Gitlab {
)
}
/// Create a group
pub fn create_group<T: AsRef<str>, P: AsRef<str>>(
&self,
name: T,
path: P,
parent_id: GroupId,
project_creation_level: AccessLevel,
auto_devops_enabled: T,
subgroup_creation_level: AccessLevel,
) -> GitlabResult<Group> {
let url = String::from("groups");
self.post_with_param(
url,
&[
("name", name.as_ref()),
("path", path.as_ref()),
("parent_id", &parent_id.to_string()),
("project_creation_level", project_creation_level.as_str()),
("auto_devops enabled", auto_devops_enabled.as_ref()),
("subgroup_creation_level", subgroup_creation_level.as_str()),
],
)
}
/// Get all accessible groups.
pub fn groups<I, K, V>(&self, params: I) -> GitlabResult<Vec<Group>>
where
......@@ -612,6 +761,20 @@ impl Gitlab {
)
}
/// Create a branch for a project
pub fn create_branch<V: AsRef<str>>(
&self,
project: ProjectId,
name: V,
reference: V,
) -> GitlabResult<RepoBranch> {
let url = format!("projects/{}/repository/branches", project);
self.post_with_param(
url,
&[("branch", name.as_ref()), ("ref", reference.as_ref())],
)
}
/// Get branches for a project.
pub fn branches<I, K, V>(&self, project: ProjectId, params: I) -> GitlabResult<Vec<RepoBranch>>
where
......@@ -620,7 +783,7 @@ impl Gitlab {
K: AsRef<str>,
V: AsRef<str>,
{
self.get_paged_with_param(format!("projects/{}/branches", project), params)
self.get_paged_with_param(format!("projects/{}/repository/branches", project), params)
}
/// Get a branch.
......@@ -1807,9 +1970,9 @@ impl Gitlab {
let req = self.client.get(page_url);
let page: Vec<T> = self.send(req)?;
let page_len = page.len();
results.extend(page);
// Gitlab used to have issues returning paginated results; these have been fixed since,
// but if it is needed, the bug manifests as Gitlab returning *all* results instead of
// just the requested results. This can cause an infinite loop here if the number of
......@@ -1828,6 +1991,7 @@ pub struct GitlabBuilder {
protocol: &'static str,
host: String,
token: Token,
cert_validation: CertPolicy,
}
impl GitlabBuilder {
......@@ -1841,6 +2005,7 @@ impl GitlabBuilder {
protocol: "https",
host: host.to_string(),
token: Token::Private(token.to_string()),
cert_validation: CertPolicy::Default,
}
}
......@@ -1850,6 +2015,11 @@ impl GitlabBuilder {
self
}
pub fn cert_insecure(&mut self) -> &mut Self {
self.cert_validation = CertPolicy::Insecure;
self
}
/// Switch to using an OAuth2 token instead of a personal access token
pub fn oauth2_token(&mut self) -> &mut Self {
if let Token::Private(token) = self.token.clone() {
......@@ -1859,6 +2029,11 @@ impl GitlabBuilder {
}
pub fn build(&self) -> GitlabResult<Gitlab> {
Gitlab::new_impl(self.protocol, &self.host, self.token.clone())
Gitlab::new_impl(
self.protocol,
&self.host,
self.token.clone(),
self.cert_validation.clone(),
)
}
}
......@@ -727,6 +727,19 @@ impl From<u64> for AccessLevel {
}
}
impl AccessLevel {
pub fn as_str(&self) -> &str {
match self {
AccessLevel::Owner => "owner",
AccessLevel::Developer => "developer",
AccessLevel::Anonymous => "anonymous",
AccessLevel::Guest => "guest",
AccessLevel::Maintainer => "maintainer",
AccessLevel::Reporter => "reporter",
}
}
}
impl Display for AccessLevel {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{}", Into::<u64>::into(*self))
......@@ -2693,3 +2706,43 @@ pub struct EventLabel {
/// The description of the label.
pub description: Option<String>,
}
#[derive(Deserialize, Debug, Clone)]
pub struct RepoFile {
pub file_path: String,
pub branch: String,
}
#[derive(Debug, Clone)]
pub enum ProjectFeatures {
Issues(FeatureVisibilityLevel),
Repository(FeatureVisibilityLevel),
MergeRequests(FeatureVisibilityLevel),
Builds(FeatureVisibilityLevel),
Wiki(FeatureVisibilityLevel),
Snippets(FeatureVisibilityLevel),
}
impl ProjectFeatures {
pub fn name(&self) -> &'static str {
match self {
ProjectFeatures::Issues(_) => "issues_access_level",
ProjectFeatures::Repository(_) => "repository_access_level",
ProjectFeatures::MergeRequests(_) => "merge_requests_access_level",
ProjectFeatures::Builds(_) => "builds_access_level",
ProjectFeatures::Wiki(_) => "wiki_access_level",
ProjectFeatures::Snippets(_) => "snippets_access_level",
}
}
pub fn access_level(&self) -> &FeatureVisibilityLevel {
match self {
ProjectFeatures::Issues(a)
| ProjectFeatures::Repository(a)
| ProjectFeatures::MergeRequests(a)
| ProjectFeatures::Builds(a)
| ProjectFeatures::Wiki(a)
| ProjectFeatures::Snippets(a) => a,
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment