Class: GithubOrgManager::Manager
- Inherits:
-
Object
- Object
- GithubOrgManager::Manager
- Defined in:
- lib/github_org_manager.rb
Overview
Manages an organization in GitHub, currently in a READONLY fashion for syncing purposes.
Constant Summary collapse
- DEV_HOME =
Where your development files are stored
File.join(Dir.home, "dev")
- OCTOKIT_PARAMS =
Default login params for Octokit, currently relies on OAuth tokens in ‘~/.netrc`:
{ netrc: true }
Instance Attribute Summary collapse
-
#client ⇒ Object
readonly
Returns the value of attribute client.
-
#dev_home ⇒ Object
readonly
Returns the value of attribute dev_home.
-
#org_name ⇒ Object
readonly
Returns the value of attribute org_name.
-
#username ⇒ Object
readonly
Returns the value of attribute username.
Instance Method Summary collapse
-
#all_repos ⇒ Hash<String, String>
All unscoped repos belonging to an organization.
-
#clear_cache! ⇒ void
If for whatever reason you need to unset all the cached instance variables for refreshing data.
-
#ensure_repo_directories_exist! ⇒ void
Make sure that every repo in the organization exists on this machine.
-
#initialize(org_name:, team_only: false, dev_home: DEV_HOME, octokit_params: OCTOKIT_PARAMS, &octokit_configuration) ⇒ Manager
constructor
Creates a new Manager.
-
#my_repo_names ⇒ Set<String>
Repos that the current logged in user has authority over.
-
#my_repos ⇒ Hash<String, String>
Repos that the current user in Octokit is a member of a team.
-
#my_teams ⇒ Set<String>
Teams that the current logged in user belongs to.
-
#org_teams ⇒ Hash<String, Numeric>
Gets teams under the current organization.
-
#repo_paths ⇒ Hash<String, String>
File paths of all repos currently in scope for your organization.
-
#repos ⇒ Hash<String, String>
Repositories in the organization the Manager is targeting.
-
#team_members ⇒ Hash<String, Array<String>>
Members that belong to each team.
-
#team_repos ⇒ Hash<String, Array<String>>
Repos that each team manages, may have overlaps.
-
#update_repos! ⇒ void
Update all repos, scoped to team if ‘team_only` is on.
Constructor Details
#initialize(org_name:, team_only: false, dev_home: DEV_HOME, octokit_params: OCTOKIT_PARAMS, &octokit_configuration) ⇒ Manager
Creates a new Manager
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/github_org_manager.rb', line 42 def initialize( org_name:, team_only: false, dev_home: DEV_HOME, octokit_params: OCTOKIT_PARAMS, &octokit_configuration ) path_name = Pathname.new(dev_home) File.directory?(path_name) or raise "Directory does not exist: #{path_name}" @dev_home = path_name @org_name = org_name @org_path = File.join(@dev_home, org_name) @client = get_client(octokit_params:, &octokit_configuration) @username = client.user[:login] @team_only = team_only end |
Instance Attribute Details
#client ⇒ Object (readonly)
Returns the value of attribute client.
22 23 24 |
# File 'lib/github_org_manager.rb', line 22 def client @client end |
#dev_home ⇒ Object (readonly)
Returns the value of attribute dev_home.
22 23 24 |
# File 'lib/github_org_manager.rb', line 22 def dev_home @dev_home end |
#org_name ⇒ Object (readonly)
Returns the value of attribute org_name.
22 23 24 |
# File 'lib/github_org_manager.rb', line 22 def org_name @org_name end |
#username ⇒ Object (readonly)
Returns the value of attribute username.
22 23 24 |
# File 'lib/github_org_manager.rb', line 22 def username @username end |
Instance Method Details
#all_repos ⇒ Hash<String, String>
All unscoped repos belonging to an organization.
85 86 87 88 89 |
# File 'lib/github_org_manager.rb', line 85 def all_repos @all_repos ||= client.org_repos(@org_name).to_h do |repo_data| [repo_data[:name], repo_data[:html_url]] end end |
#clear_cache! ⇒ void
This method returns an undefined value.
If for whatever reason you need to unset all the cached instance variables for refreshing data.
220 221 222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/github_org_manager.rb', line 220 def clear_cache! @repos = nil @repo_paths = nil @all_repos = nil @my_repos = nil @org_teams = nil @team_repos = nil @team_members = nil @my_teams = nil @my_repo_names = nil true end |
#ensure_repo_directories_exist! ⇒ void
This method returns an undefined value.
Make sure that every repo in the organization exists on this machine. Scoped to team if ‘team_only` is on.
161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/github_org_manager.rb', line 161 def ensure_repo_directories_exist! Dir.mkdir(@org_path) unless Dir.exist?(@org_path) Dir.chdir(@org_path) do repos.each do |name, html_url| `git clone "#{html_url}"` unless Dir.exist?(@repo_paths[name]) end end true end |
#my_repo_names ⇒ Set<String>
Repos that the current logged in user has authority over.
149 150 151 152 153 154 155 |
# File 'lib/github_org_manager.rb', line 149 def my_repo_names @my_repo_names ||= team_repos .select { |name, _| my_teams.include?(name) } .values .flatten .then { Set.new(_1) } end |
#my_repos ⇒ Hash<String, String>
Repos that the current user in Octokit is a member of a team. of that manages that repo.
96 97 98 99 100 |
# File 'lib/github_org_manager.rb', line 96 def my_repos @my_repos ||= all_repos.select do |name, _| my_repo_names.include?(name) end end |
#my_teams ⇒ Set<String>
Teams that the current logged in user belongs to.
138 139 140 141 142 143 |
# File 'lib/github_org_manager.rb', line 138 def my_teams @my_teams ||= team_members .select { |_, members| members.include?(@username) } .keys .then { Set.new(_1) } end |
#org_teams ⇒ Hash<String, Numeric>
Gets teams under the current organization.
106 107 108 109 110 |
# File 'lib/github_org_manager.rb', line 106 def org_teams @org_teams ||= client.org_teams(@org_name).to_h do [_1[:name], _1[:id]] end end |
#repo_paths ⇒ Hash<String, String>
File paths of all repos currently in scope for your organization.
75 76 77 78 79 |
# File 'lib/github_org_manager.rb', line 75 def repo_paths @repo_paths ||= repos.to_h do |repo_name, _repo_url| [repo_name, File.join(@org_path, repo_name)] end end |
#repos ⇒ Hash<String, String>
Repositories in the organization the Manager is targeting. These values can be scoped to only ones owned by the username specified to Octokit with the ‘team_only` option.
67 68 69 |
# File 'lib/github_org_manager.rb', line 67 def repos @repos ||= @team_only ? my_repos : team_repos end |
#team_members ⇒ Hash<String, Array<String>>
Members that belong to each team.
128 129 130 131 132 |
# File 'lib/github_org_manager.rb', line 128 def team_members @team_members ||= org_teams.to_h do |name, id| [name, client.team_members(id).map { _1[:login] }] end end |
#team_repos ⇒ Hash<String, Array<String>>
Repos that each team manages, may have overlaps.
117 118 119 120 121 |
# File 'lib/github_org_manager.rb', line 117 def team_repos @team_repos ||= org_teams.to_h do |name, id| [name, client.team_repos(id).map { _1[:name] }] end end |
#update_repos! ⇒ void
This method returns an undefined value.
Update all repos, scoped to team if ‘team_only` is on.
TODO: While there is a Ruby Git gem I’ve had some difficulty in getting it to work properly, hence plain old system commands instead for the time being.
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/github_org_manager.rb', line 180 def update_repos! # Hard to update repos which don't exist on the computer, make sure that # we have them all already downloaded, or do so ensure_repo_directories_exist! puts "📦 Updating #{repo_paths.size} repos: \n" repo_paths.each do |name, path| Dir.chdir(path) do main_branch = `basename $(git symbolic-ref refs/remotes/origin/HEAD)` || "main" current_branch = `git rev-parse --abbrev-ref HEAD` on_main = main_branch == current_branch no_changes = `git diff --stat`.empty? puts " Updating #{name}:" puts " Stashing any potential changes" unless no_changes `git stash` unless no_changes puts " Checking out #{main_branch}" unless on_main `git checkout #{main_branch}` unless on_main puts " Pulling changes" `git pull` puts " Returning to previous branch #{current_branch}" unless on_main `git checkout #{current_branch}` unless on_main puts " Popping stash" unless no_changes `git stash pop` unless no_changes end end true end |