Skip to content

Commit

Permalink
Merge pull request #43 from Chocrates/fix-csv-errors
Browse files Browse the repository at this point in the history
continuing through csv list after a failure
  • Loading branch information
Chris McIntosh authored Aug 31, 2022
2 parents b42e3f1 + 65ee36e commit f58d1ac
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 126 deletions.
260 changes: 135 additions & 125 deletions src/commands/transfer_repositories.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ impl FromStr for TeamPermissions {
type Err = ();
fn from_str(input: &str) -> Result<TeamPermissions, Self::Err> {
match input.to_lowercase().as_str() {
"pull" => Ok(TeamPermissions::Pull),
"read" => Ok(TeamPermissions::Pull),
"write" => Ok(TeamPermissions::Push),
"maintain" => Ok(TeamPermissions::Maintain),
Expand Down Expand Up @@ -91,156 +92,165 @@ pub async fn exec(oc: Octocrab, args: TransferRepositories) -> Result<(), Box<dy
let mut teams = Vec::<Teams>::new();

// Get all teams with access to repository
let response: Vec<models::teams::Team> = oc
.get(
match oc
.get::<Vec<models::teams::Team>, reqwest::Url, ()>(
oc.absolute_url(format!("/repos/{}/{}/teams", organization, repository))?,
None::<&()>,
)
.await?;

for t in response.iter() {
let permission = match TeamPermissions::from_str(&t.permission) {
Ok(permission) => permission,
Err(_) => {
println!("Invalid permission {} for team {}", t.permission, t.name);
TeamPermissions::Pull
.await
{
Ok(response) => {
for t in response.iter() {
let permission = match TeamPermissions::from_str(&t.permission) {
Ok(permission) => permission,
Err(_) => {
println!("Invalid permission {} for team {}", t.permission, t.name);
TeamPermissions::Pull
}
};

let mut team = Teams {
name: t.name.clone(),
slug: t.slug.clone(),
permissions: permission,
members: Vec::<models::User>::new(),
};

let members: Vec<models::User> = oc
.get(
oc.absolute_url(format!(
"/orgs/{}/teams/{}/members",
organization, t.slug
))?,
None::<&()>,
)
.await?;
team.members = members.clone();
teams.push(team.clone());
}
};

let mut team = Teams {
name: t.name.clone(),
slug: t.slug.clone(),
permissions: permission,
members: Vec::<models::User>::new(),
};

let members: Vec<models::User> = oc
.get(
oc.absolute_url(format!(
"/orgs/{}/teams/{}/members",
organization, t.slug
))?,
None::<&()>,
)
.await?;
team.members = members.clone();
teams.push(team.clone());
}

let mut new_teams = Vec::<models::teams::Team>::new();
for t in teams.iter() {
let new_team: models::teams::Team;

// determine if team with this name exists in new org
match oc.teams(&target_organization).get(&t.slug).await {
Ok(team) => {
new_team = team;
} // don't need to create the team
Err(error) => match error {
octocrab::Error::GitHub {
ref source,
backtrace: _,
} => {
if source.message == "Not Found" {
new_team = oc
.teams(&target_organization)
.create(&t.name)
.privacy(params::teams::Privacy::Closed) // Make team public
.send()
.await
.expect("Team Creation Failed");
} else {
panic!("Unknown error: {}", &error);
let mut new_teams = Vec::<models::teams::Team>::new();
for t in teams.iter() {
let new_team: models::teams::Team;

// determine if team with this name exists in new org
match oc.teams(&target_organization).get(&t.slug).await {
Ok(team) => {
new_team = team;
} // don't need to create the team
Err(error) => match error {
octocrab::Error::GitHub {
ref source,
backtrace: _,
} => {
if source.message == "Not Found" {
new_team = oc
.teams(&target_organization)
.create(&t.name)
.privacy(params::teams::Privacy::Closed) // Make team public
.send()
.await
.expect("Team Creation Failed");
} else {
panic!("Unknown error: {}", &error);
}
}
_ => panic!("Unknown error: {}", &error),
},
};

// add users to team
for user in t.members.iter() {
let body = reqwest::Body::from("{\"role\":\"member\"}");

match oc
.request_builder(
oc.absolute_url(format!(
"/orgs/{}/teams/{}/memberships/{}",
target_organization, new_team.slug, user.login
))?,
reqwest::Method::PUT,
)
.body(body)
.send()
.await
{
// Users that are not in the org will still return an HTTP 200, so all errors
// are going to be unrecoverable and thrown to the user
Ok(_) => {}
Err(error) => {
panic!("Unknown error {}", &error);
}
}
}
_ => panic!("Unknown error: {}", &error),
},
};

// add users to team
for user in t.members.iter() {
let body = reqwest::Body::from("{\"role\":\"member\"}");
new_teams.push(new_team);
}

let team_ids = new_teams
.iter()
.map(|t| format!("{}", t.id))
.collect::<Vec<String>>()
.join(",");

// Transfer Team to new org
// Teams will not have proper permissions
let body = reqwest::Body::from(format!(
"{{\"new_owner\":\"{}\", \"team_ids\":[{}]}}",
target_organization, &team_ids
));

match oc
.request_builder(
oc.absolute_url(format!(
"/orgs/{}/teams/{}/memberships/{}",
target_organization, new_team.slug, user.login
"/repos/{}/{}/transfer",
organization, repository
))?,
reqwest::Method::PUT,
reqwest::Method::POST,
)
.body(body)
.send()
.await
{
// Users that are not in the org will still return an HTTP 200, so all errors
// are going to be unrecoverable and thrown to the user
Ok(_) => {}
Ok(_) => {
println!("Transferred: {}/{}", target_organization, repository);
}
Err(error) => {
panic!("Unknown error {}", &error);
panic!("Unknown error: {}", &error);
}
}
}

new_teams.push(new_team);
}
if args.enable_actions {
let one_second = time::Duration::from_millis(1000);

let team_ids = new_teams
.iter()
.map(|t| format!("{}", t.id))
.collect::<Vec<String>>()
.join(",");

// Transfer Team to new org
// Teams will not have proper permissions
let body = reqwest::Body::from(format!(
"{{\"new_owner\":\"{}\", \"team_ids\":[{}]}}",
target_organization, &team_ids
));

match oc
.request_builder(
oc.absolute_url(format!("/repos/{}/{}/transfer", organization, repository))?,
reqwest::Method::POST,
)
.body(body)
.send()
.await
{
Ok(_) => {
println!("Transferred: {}/{}", target_organization, repository);
thread::sleep(one_second);
// Enable Actions
let body = reqwest::Body::from("{\"enabled\": true}");
match oc
.request_builder(
oc.absolute_url(format!(
"/repos/{}/{}/actions/permissions",
target_organization, repository
))?,
reqwest::Method::PUT,
)
.body(body)
.send()
.await
{
// Users that are not in the org will still return an HTTP 200, so all errors
// are going to be unrecoverable and thrown to the user
Ok(res) => {
println!("{:?}", res);
}
Err(error) => {
panic!("Unknown error {}", &error);
}
}
}
}
Err(error) => {
panic!("Unknown error: {}", &error);
}
}

if args.enable_actions {
let one_second = time::Duration::from_millis(1000);

thread::sleep(one_second);
// Enable Actions
let body = reqwest::Body::from("{\"enabled\": true}");
match oc
.request_builder(
oc.absolute_url(format!(
"/repos/{}/{}/actions/permissions",
target_organization, repository
))?,
reqwest::Method::PUT,
)
.body(body)
.send()
.await
{
// Users that are not in the org will still return an HTTP 200, so all errors
// are going to be unrecoverable and thrown to the user
Ok(res) => {
println!("{:?}", res);
}
Err(error) => {
panic!("Unknown error {}", &error);
}
println!("Unknown error for repository {} : {}", &repository, &error);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
let octocrab = Octocrab::builder()
.personal_token(cli.token)
.build()
.expect("Unable to authenticate with token");
.expect("Unable to build Octocrab instance");

match &cli.command {
Commands::DeleteRepositories(delete_repository_args) => {
Expand Down

0 comments on commit f58d1ac

Please sign in to comment.