Skip to content
Snippets Groups Projects
Commit f0ea6a3d authored by Michael Aaron Murphy's avatar Michael Aaron Murphy
Browse files

Filter by namespace on GitLab

parent 113ff2e4
No related branches found
No related tags found
No related merge requests found
......@@ -22,7 +22,7 @@ gitrepoman github pop-os clone
gitrepoman github pop-os pull
gitrepoman github pop-os checkout
gitrepoman gitlab gitlab.redox-os.org clone
gitrepoman gitlab gitlab.redox-os.org pull
gitrepoman gitlab gitlab.redox-os.org checkout
gitrepoman gitlab gitlab.redox-os.org redox-os clone
gitrepoman gitlab gitlab.redox-os.org redox-os pull
gitrepoman gitlab gitlab.redox-os.org redox-os checkout
```
use std::io;
use std::path::Path;
use std::process::Command;
use std::process::{Command, Stdio};
use rayon::prelude::*;
#[derive(Debug, Deserialize, Eq, Hash)]
......@@ -8,6 +8,7 @@ pub struct Repo {
pub name: String,
pub html_url: String,
pub ssh_url: String,
pub namespace: String,
}
impl Repo {
......@@ -35,7 +36,7 @@ pub enum GitError {
}
fn git_cmd(args: &[&str], name: &str) -> Result<String, (String, GitError)> {
match Command::new("git").args(args).status() {
match Command::new("git").args(args).stdout(Stdio::null()).stderr(Stdio::null()).status() {
Ok(status) => if status.success() {
Ok(name.to_owned())
} else {
......@@ -48,16 +49,20 @@ fn git_cmd(args: &[&str], name: &str) -> Result<String, (String, GitError)> {
pub trait GitAction {
fn get_repos(&self) -> Vec<Repo>;
fn list(&self) {
fn list(&self, namespace: &str) {
for repo in self.get_repos() {
if repo.namespace == namespace {
continue
}
println!("{}: {}", repo.name, repo.ssh_url);
}
}
fn clone(&self, flags: u8) {
fn clone(&self, flags: u8, namespace: &str) {
let results = self.get_repos()
.par_iter()
.inspect(|repo| println!("cloning {}", repo.name))
.filter(|repo| namespace == "" || repo.name == namespace)
.inspect(|repo| println!("cloning {} from {}", repo.name, repo.get_url()))
.map(|repo| if !Path::new(&repo.name).exists() {
let url = if flags & 0b01 != 0 { repo.get_ssh_url() } else { repo.get_url() };
git_cmd(&["clone", "--recursive", url, &repo.name], &repo.name)
......@@ -74,10 +79,11 @@ pub trait GitAction {
}
}
fn pull(&self, flags: u8) {
fn pull(&self, flags: u8, namespace: &str) {
let results = self.get_repos()
.par_iter()
.inspect(|repo| println!("pulling {}", repo.name))
.filter(|repo| namespace == "" || repo.name == namespace)
.inspect(|repo| println!("pulling {} from {}", repo.name, repo.get_url()))
.map(|repo| if !Path::new(&repo.name).exists() {
let url = if flags & 0b01 != 0 { repo.get_ssh_url() } else { repo.get_url() };
git_cmd(&["clone", "--recursive", url, &repo.name], &repo.name)
......@@ -96,10 +102,11 @@ pub trait GitAction {
}
}
fn checkout(&self, flags: u8) {
fn checkout(&self, flags: u8, namespace: &str) {
let results = self.get_repos()
.par_iter()
.inspect(|repo| println!("checking out {}", repo.name))
.filter(|repo| namespace == "" || repo.name == namespace)
.inspect(|repo| println!("checking out {} from {}", repo.name, repo.get_url()))
.map(|repo| if !Path::new(&repo.name).exists() {
let url = if flags & 0b01 != 0 { repo.get_ssh_url() } else { repo.get_url() };
git_cmd(&["clone", "--recursive", url, &repo.name], &repo.name)
......
......@@ -15,18 +15,30 @@ impl GitHub {
}
}
#[derive(Debug, Deserialize)]
pub struct GithubRepo {
pub name: String,
pub html_url: String,
pub ssh_url: String,
}
impl GitAction for GitHub {
fn get_repos(&self) -> Vec<Repo> {
let mut output = HashSet::new();
for page in 0.. {
let request = self.client.get()
.custom_endpoint(&format!("orgs/{}/repos?page={}", self.org, page))
.execute::<Vec<Repo>>();
.execute::<Vec<GithubRepo>>();
if let Ok((_, _, Some(repos))) = request {
if repos.len() > 0 {
for repo in repos {
output.insert(repo);
output.insert(Repo {
name: repo.name,
html_url: repo.html_url,
ssh_url: repo.ssh_url,
namespace: "".into()
});
}
} else {
break
......
......@@ -10,7 +10,8 @@ impl GitAction for Gitlab {
repos.push(Repo {
name: project.name,
html_url: project.http_url_to_repo,
ssh_url: project.ssh_url_to_repo
ssh_url: project.ssh_url_to_repo,
namespace: project.namespace.full_path,
})
}
}
......
......@@ -34,15 +34,12 @@ fn main() {
.long("force")
.short("f"))
.subcommand(SubCommand::with_name("gitlab")
.arg(Arg::with_name("DOMAIN")
.required(true))
.arg(Arg::with_name("ACTION")
.required(true)))
.arg(Arg::with_name("DOMAIN").required(true))
.arg(Arg::with_name("NAMESPACE").required(true))
.arg(Arg::with_name("ACTION").required(true)))
.subcommand(SubCommand::with_name("github")
.arg(Arg::with_name("DOMAIN")
.required(true))
.arg(Arg::with_name("ACTION")
.required(true)))
.arg(Arg::with_name("DOMAIN").required(true))
.arg(Arg::with_name("ACTION").required(true)))
.get_matches();
let config = match Config::new() {
......@@ -56,57 +53,57 @@ fn main() {
let flags = if matches.occurrences_of("ssh") > 0 { 0b01 } else { 0b00 }
+ if matches.occurrences_of("force") > 0 { 0b10 } else { 0b00 };
let (source, org, action) = if let Some(matches) = matches.subcommand_matches("gitlab") {
(GitService::GitLab, matches.value_of("DOMAIN").unwrap(), matches.value_of("ACTION").unwrap())
let (source, org, action, ns) = if let Some(matches) = matches.subcommand_matches("gitlab") {
(
GitService::GitLab,
matches.value_of("DOMAIN").unwrap(),
matches.value_of("ACTION").unwrap(),
matches.value_of("NAMESPACE").unwrap_or("")
)
} else if let Some(matches) = matches.subcommand_matches("github") {
(GitService::GitHub, matches.value_of("DOMAIN").unwrap(), matches.value_of("ACTION").unwrap())
(
GitService::GitHub,
matches.value_of("DOMAIN").unwrap(),
matches.value_of("ACTION").unwrap(),
""
)
} else {
eprintln!("no subcommand provided");
exit(1);
};
let authenticated: Box<GitAction> = match source {
GitService::GitHub => {
let token = match config.github {
macro_rules! client {
($name:tt, $token:expr) => {{
let token = match $token {
Some(token) => token,
None => {
eprintln!("no GitHub token provided");
eprintln!("no {} token provided", stringify!($name));
exit(1);
}
};
match GitHub::new(org.to_owned(), token) {
match $name::new(org.to_owned(), token) {
Ok(client) => Box::new(client),
Err(why) => {
eprintln!("unable to authenticate client: {}", why);
exit(1);
}
}
},
GitService::GitLab => {
let token = match config.gitlab {
Some(token) => token,
None => {
eprintln!("no GitLab token provided");
exit(1);
}
};
match Gitlab::new(org.to_owned(), token) {
Ok(client) => Box::new(client),
Err(why) => {
eprintln!("unable to authenticate client: {}", why);
exit(1);
}
}
}
}};
}
let authenticated: Box<GitAction> = match source {
GitService::GitHub => client!(GitHub, config.github),
GitService::GitLab => client!(Gitlab, config.gitlab),
};
match Action::from(action) {
Ok(Action::List) => authenticated.list(),
Ok(Action::Clone) => authenticated.clone(flags),
Ok(Action::Pull) => authenticated.pull(flags),
Ok(Action::Checkout) => authenticated.checkout(flags),
Ok(Action::List) => authenticated.list(ns),
Ok(Action::Clone) => authenticated.clone(flags, ns),
Ok(Action::Pull) => authenticated.pull(flags, ns),
Ok(Action::Checkout) => authenticated.checkout(flags, ns),
Err(cmd) => {
eprintln!("{} is not a valid command", cmd);
exit(1);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment