[Tutorial] PyGithub 2

With the aid of my boss I got to work on a much better version of the code that I was attempting earlier.

This program assumes two .json files: a list of projects and a list of teams. The projects .json file will have projects and within projects repositories and teams with access to those repositories. Within the teams .json there will be a list of teams and which users are members of them.

So teams will look something like:

{

"A-Team": {

    "members": ["auser", "buser",  "cuser"]

    },

"B-Team": {

    "members": ["auser", "buser"]

    },

"C-Team": {

    "members": ["buser",  "cuser"]

    },

"D-Team": {

    "members": ["cuser"]

    }

}

And projects:

{
"project1": {

    "repos": "testproject1",

    "teams": ["A-Team","B-Team", "C-Team"]

},

"project2": {

    "repos": "testproject2",

    "teams": ["A-Team"]

},

"project3": {

    "repos": "testproject3",

    "teams": ["B-Team", "C-Team"]

    }
}

Important things to note when making .json files: you need to use double quotes (” “) and you need to make sure that you don’t have trailing commas. Basically don’t have a comma followed by nothing, which you can get away with in Python but isn’t cool here.

I need to read the .json files so:

import json
with open(“projects.json”, “r”) as f:
    projects_data = json.loads(f.read())
with open(“teams.json”, “r”) as f:
    teams_data = json.loads(f.read())
This will create two dictionaries, projects_data and teams_data.
from github import Github
g = Github(“token”)
We need to create a github object as usual.
Let’s get all the members in the Organization:
org_members = []
for teams in teams_data.values():
    org_members.extend(teams[‘members’])
There’s a lot of loops and nested loops so I’m trying to keep things straight. For teams in teams_data.values() . .values() will return a list of all values in a dictionary. Then we specify the ‘members’ keys, which will return lists, lists that we then attach to org_members, creating a list of all members in the Organization.
The problem with this? There will be duplicates. So to deal with the duplicates we turn it into a set.
o = set(org_members)
I think we can just turn it back into a list through the list() function later if we need it.
Get the Organization github object:
org = g.get_organization(“organization-example”)
#already created test organization
We need to link up repositories and teams they’re linked to. The solution was to modify the python object teams_data, basically creating a new element in the dictionaries called repos.
for repo_name, repo in projects_data.items():
# This goes through the dictionary items in projects_data
  for team in repo[‘teams’]:
# So in each item for projects_data there’s ‘teams’ and ‘repos’
# this grabs each team in ‘teams’
    if “repos” not in teams_data[team]:
# If there is no “repos” element in teams_data, create one as
# an empty list
      teams_data[team][“repos”] = []
# When this exists, then add the repo name
    teams_data[team[“repos”].append(repo_name)
This above code will create a new section in teams_data that lists the repos that are associated with each team. This is to save us from having to do loops to figure out if repos are associated with which teams later on by having to compare the two different .json files.
Get a list of current members in an Organization:
current_members = {x.login: x for x in org.get_members()}
This is the usual creating a dictionary with the key being the login names for users on Github. We use “login” because it turns out the “name” can be “None” which isn’t useful.
Get a list of current teams in an Organization:
current_teams = {x.name: x for x in org.get_teams()}
This returns a dictionary with a key of team names. This allows us to select a team simply by using its name.
Delete team members who are on teams but aren’t supposed to be on the teams:
for name, team in current_teams.items():
    if name not in teams_data:
        team.delete()
Get the name and the team from the items in current_teams, then check if the name is also in teams_data. If it is not, delete that team.
Name gives you the name of the team, team (in this case) is a literal team in the current_teams.items().
If teams do not exist, create them. For lists that should not exist, delete them.
for name, team_data in teams_data.items():
    if name in current_teams:
        team = current_teams[name]
    else:
        team = org.create_team(name)
    for member in team.get_members():
        if member.login not in team_data[“members”]:
            team.remove_from_members(member)
    for member in team_data[‘members’]:
        team.add_to_members(current_members[member])
So get the name and team_data in the dictionary items for teams_data.
If the name of that team is listed in current_teams then set team equal to that specific team.
Else, create the team with that name.
A similar check for members follows.
For each team, check each member in the team.
If the member is not in the team_data[“members”] list then remove the member from the team.
If the member is not in the team_data[“member”] list, then remove the member from the team.
For member in the team_data[“members”] list, add members to the specified team that was created above.
This adds the listed team members to the actual Github team object.
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s