diff --git a/src/commands/transfer_repositories.rs b/src/commands/transfer_repositories.rs index cd2d430..6b02d76 100644 --- a/src/commands/transfer_repositories.rs +++ b/src/commands/transfer_repositories.rs @@ -47,6 +47,7 @@ impl FromStr for TeamPermissions { type Err = (); fn from_str(input: &str) -> Result { match input.to_lowercase().as_str() { + "pull" => Ok(TeamPermissions::Pull), "read" => Ok(TeamPermissions::Pull), "write" => Ok(TeamPermissions::Push), "maintain" => Ok(TeamPermissions::Maintain), @@ -91,156 +92,165 @@ pub async fn exec(oc: Octocrab, args: TransferRepositories) -> Result<(), Box::new(); // Get all teams with access to repository - let response: Vec = oc - .get( + match oc + .get::, 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::::new(), + }; + + let members: Vec = 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::::new(), - }; - - let members: Vec = 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::::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::::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::>() + .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::>() - .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); } } } diff --git a/src/main.rs b/src/main.rs index 353ac69..833018a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -34,7 +34,7 @@ async fn main() -> Result<(), Box> { 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) => {