github_org_manager 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/Gemfile.lock +1 -1
- data/README.md +13 -3
- data/lib/github_org_manager/version.rb +1 -1
- data/lib/github_org_manager.rb +141 -16
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 448927c5116bc5a19aa7eb3ede1e38fbf835014d385f1b3060958c18b72fb72d
|
4
|
+
data.tar.gz: dbae6b024e64729cefb7c424c8c994989ce40deeeab2a111fc457a2108d45fe7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5bfe6d464a78f395d4be6e6697b835c759bc7e940dfd8105be7ede6097783c1ef4493abb63ed8f2e83e822416e3d669b4b2041728661988ccb779b5d0182a91e
|
7
|
+
data.tar.gz: 3810347e3e5ee96b03ea119380b5016cff5b48da980efc6dd6c720955e409b91132d932eef0f19da48bfdf4f10531af15f9db345a96f2f7e1b0b149769201fca
|
data/CHANGELOG.md
CHANGED
@@ -1,8 +1,14 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.0.3] - 2022-02-18
|
4
|
+
|
5
|
+
- Adds ability to limit scope to teams the current user is on
|
6
|
+
- Exposes information on team membership, repos, and current user affiliations
|
7
|
+
|
3
8
|
## [0.0.2] - 2022-02-17
|
4
9
|
|
5
10
|
- Fix old `CLIENT` reference from `0.0.1`
|
11
|
+
|
6
12
|
## [0.0.1] - 2022-02-17
|
7
13
|
|
8
14
|
- Initial release
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -10,6 +10,12 @@ manager = GithubOrgManager::Manager.new(
|
|
10
10
|
# more accurately read from for now.
|
11
11
|
org_name: "<YOUR_ORG_HERE>",
|
12
12
|
|
13
|
+
# If you would like to limit this to only teams that the
|
14
|
+
# "logged in" user currently belongs to, set this to
|
15
|
+
# true and all downloads and updates will be scoped as
|
16
|
+
# such.
|
17
|
+
team_only: true,
|
18
|
+
|
13
19
|
# Directory where your code typically is, defaults to
|
14
20
|
# `~/dev` and ensures it exists
|
15
21
|
dev_home: "<WHERE_YOUR_CODE_LIVES>",
|
@@ -45,11 +51,15 @@ gem 'github_org_manager'
|
|
45
51
|
|
46
52
|
And then execute:
|
47
53
|
|
48
|
-
|
54
|
+
```sh
|
55
|
+
$ bundle install
|
56
|
+
```
|
49
57
|
|
50
58
|
Or install it yourself as:
|
51
59
|
|
52
|
-
|
60
|
+
```sh
|
61
|
+
$ gem install github_org_manager
|
62
|
+
```
|
53
63
|
|
54
64
|
## Development
|
55
65
|
|
@@ -59,7 +69,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
59
69
|
|
60
70
|
## Contributing
|
61
71
|
|
62
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
72
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/baweaver/github_org_manager. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/baweaver/github_org_manager/blob/main/CODE_OF_CONDUCT.md).
|
63
73
|
|
64
74
|
## License
|
65
75
|
|
data/lib/github_org_manager.rb
CHANGED
@@ -6,6 +6,9 @@ require "octokit"
|
|
6
6
|
require "netrc"
|
7
7
|
|
8
8
|
module GithubOrgManager
|
9
|
+
# Manages an organization in GitHub, currently in a
|
10
|
+
# READONLY fashion for syncing purposes.
|
11
|
+
#
|
9
12
|
class Manager
|
10
13
|
# Where your development files are stored
|
11
14
|
DEV_HOME = File.join(Dir.home, "dev")
|
@@ -16,23 +19,29 @@ module GithubOrgManager
|
|
16
19
|
# ( https://github.com/octokit/octokit.rb#using-a-netrc-file )
|
17
20
|
OCTOKIT_PARAMS = { netrc: true }
|
18
21
|
|
19
|
-
attr_reader :
|
22
|
+
attr_reader :client, :dev_home, :org_name, :username
|
20
23
|
|
21
24
|
# Creates a new Manager
|
22
25
|
#
|
23
26
|
# @param org_name: [String]
|
24
|
-
# Organization to pull data from
|
27
|
+
# Organization to pull data from.
|
28
|
+
#
|
29
|
+
# @param team_only: [Boolean]
|
30
|
+
# Scope all data to only teams in the organization
|
31
|
+
# you belong to, meaning all syncing applies only to
|
32
|
+
# teams you're specifically on.
|
25
33
|
#
|
26
34
|
# @param dev_home: [String]
|
27
|
-
# Where development files and repos live on your machine
|
35
|
+
# Where development files and repos live on your machine.
|
28
36
|
#
|
29
37
|
# @param octokit_params [Hash<Symbol, Any>]
|
30
|
-
# Params passed through to Octokit::Client constructor
|
38
|
+
# Params passed through to `Octokit::Client` constructor.
|
31
39
|
#
|
32
40
|
# @param &octokit_configuration [Proc]
|
33
|
-
# Configuration block passed to Octokit.configure
|
41
|
+
# Configuration block passed to `Octokit.configure`.
|
34
42
|
def initialize(
|
35
43
|
org_name:,
|
44
|
+
team_only: false,
|
36
45
|
dev_home: DEV_HOME,
|
37
46
|
octokit_params: OCTOKIT_PARAMS,
|
38
47
|
&octokit_configuration
|
@@ -42,26 +51,118 @@ module GithubOrgManager
|
|
42
51
|
|
43
52
|
@dev_home = path_name
|
44
53
|
@org_name = org_name
|
45
|
-
@org_path = File.join(
|
54
|
+
@org_path = File.join(@dev_home, org_name)
|
55
|
+
|
56
|
+
@client = get_client(octokit_params:, &octokit_configuration)
|
57
|
+
@username = client.user[:login]
|
58
|
+
@team_only = team_only
|
59
|
+
end
|
60
|
+
|
61
|
+
# Repositories in the organization the Manager is targeting. These
|
62
|
+
# values can be scoped to only ones owned by the username specified
|
63
|
+
# to Octokit with the `team_only` option.
|
64
|
+
#
|
65
|
+
# @return [Hash<String, String>]
|
66
|
+
# Mapping of repo name to repo URL
|
67
|
+
def repos
|
68
|
+
@repos ||= @team_only ? my_repos : team_repos
|
69
|
+
end
|
46
70
|
|
47
|
-
|
71
|
+
# File paths of all repos currently in scope for your organization.
|
72
|
+
#
|
73
|
+
# @return [Hash<String, String>]
|
74
|
+
# Mapping of repo name to repo file path.
|
75
|
+
def repo_paths
|
76
|
+
@repo_paths ||= repos.to_h do |repo_name, _repo_url|
|
77
|
+
[repo_name, File.join(@org_path, repo_name)]
|
78
|
+
end
|
79
|
+
end
|
48
80
|
|
49
|
-
|
81
|
+
# All unscoped repos belonging to an organization.
|
82
|
+
#
|
83
|
+
# @return [Hash<String, String>]
|
84
|
+
# Mapping of repo name to repo URL.
|
85
|
+
def all_repos
|
86
|
+
@all_repos ||= client.org_repos(@org_name).to_h do |repo_data|
|
50
87
|
[repo_data[:name], repo_data[:html_url]]
|
51
88
|
end
|
89
|
+
end
|
52
90
|
|
53
|
-
|
54
|
-
|
91
|
+
# Repos that the current user in Octokit is a member of a team.
|
92
|
+
# of that manages that repo.
|
93
|
+
#
|
94
|
+
# @return [Hash<String, String>]
|
95
|
+
# Mapping of repo name to repo URL.
|
96
|
+
def my_repos
|
97
|
+
@my_repos ||= all_repos.select do |name, _|
|
98
|
+
my_repo_names.include?(name)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Gets teams under the current organization.
|
103
|
+
#
|
104
|
+
# @return [Hash<String, Numeric>]
|
105
|
+
# Mapping of team name to team id.
|
106
|
+
def org_teams
|
107
|
+
@org_teams ||= client.org_teams(@org_name).to_h do
|
108
|
+
[_1[:name], _1[:id]]
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# Repos that each team manages, may have overlaps.
|
113
|
+
#
|
114
|
+
# @return [Hash<String, Array<String>>]
|
115
|
+
# Mapping of team name to a collection of repo names
|
116
|
+
# that they manage.
|
117
|
+
def team_repos
|
118
|
+
@team_repos ||= org_teams.to_h do |name, id|
|
119
|
+
[name, client.team_repos(id).map { _1[:name] }]
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# Members that belong to each team.
|
124
|
+
#
|
125
|
+
# @return [Hash<String, Array<String>>]
|
126
|
+
# Mapping of team name to a collection of all of its
|
127
|
+
# members.
|
128
|
+
def team_members
|
129
|
+
@team_members ||= org_teams.to_h do |name, id|
|
130
|
+
[name, client.team_members(id).map { _1[:login] }]
|
55
131
|
end
|
56
132
|
end
|
57
133
|
|
134
|
+
# Teams that the current logged in user belongs to.
|
135
|
+
#
|
136
|
+
# @return [Set<String>]
|
137
|
+
# Names of teams.
|
138
|
+
def my_teams
|
139
|
+
@my_teams ||= team_members
|
140
|
+
.select { |_, members| members.include?(@username) }
|
141
|
+
.keys
|
142
|
+
.then { Set.new(_1) }
|
143
|
+
end
|
144
|
+
|
145
|
+
# Repos that the current logged in user has authority over.
|
146
|
+
#
|
147
|
+
# @return [Set<String>]
|
148
|
+
# Names of repos.
|
149
|
+
def my_repo_names
|
150
|
+
@my_repo_names ||= team_repos
|
151
|
+
.select { |name, _| my_teams.include?(name) }
|
152
|
+
.values
|
153
|
+
.flatten
|
154
|
+
.then { Set.new(_1) }
|
155
|
+
end
|
156
|
+
|
58
157
|
# Make sure that every repo in the organization exists on this
|
59
|
-
# machine.
|
158
|
+
# machine. Scoped to team if `team_only` is on.
|
159
|
+
#
|
160
|
+
# @return [void]
|
60
161
|
def ensure_repo_directories_exist!
|
61
162
|
Dir.mkdir(@org_path) unless Dir.exist?(@org_path)
|
62
163
|
|
63
164
|
Dir.chdir(@org_path) do
|
64
|
-
|
165
|
+
repos.each do |name, html_url|
|
65
166
|
`git clone "#{html_url}"` unless Dir.exist?(@repo_paths[name])
|
66
167
|
end
|
67
168
|
end
|
@@ -69,15 +170,21 @@ module GithubOrgManager
|
|
69
170
|
true
|
70
171
|
end
|
71
172
|
|
72
|
-
# Update all repos
|
173
|
+
# Update all repos, scoped to team if `team_only` is on.
|
174
|
+
#
|
175
|
+
# TODO: While there is a Ruby Git gem I've had some difficulty
|
176
|
+
# in getting it to work properly, hence plain old system commands
|
177
|
+
# instead for the time being.
|
178
|
+
#
|
179
|
+
# @return [void]
|
73
180
|
def update_repos!
|
74
181
|
# Hard to update repos which don't exist on the computer, make sure that
|
75
182
|
# we have them all already downloaded, or do so
|
76
183
|
ensure_repo_directories_exist!
|
77
184
|
|
78
|
-
puts "📦 Updating #{
|
185
|
+
puts "📦 Updating #{repo_paths.size} repos: \n"
|
79
186
|
|
80
|
-
|
187
|
+
repo_paths.each do |name, path|
|
81
188
|
Dir.chdir(path) do
|
82
189
|
main_branch = `basename $(git symbolic-ref refs/remotes/origin/HEAD)` || "main"
|
83
190
|
current_branch = `git rev-parse --abbrev-ref HEAD`
|
@@ -106,7 +213,25 @@ module GithubOrgManager
|
|
106
213
|
true
|
107
214
|
end
|
108
215
|
|
109
|
-
|
216
|
+
# If for whatever reason you need to unset all the cached
|
217
|
+
# instance variables for refreshing data.
|
218
|
+
#
|
219
|
+
# @return [void]
|
220
|
+
def clear_cache!
|
221
|
+
@repos = nil
|
222
|
+
@repo_paths = nil
|
223
|
+
@all_repos = nil
|
224
|
+
@my_repos = nil
|
225
|
+
@org_teams = nil
|
226
|
+
@team_repos = nil
|
227
|
+
@team_members = nil
|
228
|
+
@my_teams = nil
|
229
|
+
@my_repo_names = nil
|
230
|
+
|
231
|
+
true
|
232
|
+
end
|
233
|
+
|
234
|
+
private def get_client(octokit_params: OCTOKIT_PARAMS, &configuration)
|
110
235
|
return @client if defined?(@client)
|
111
236
|
|
112
237
|
Octokit.configure(&configuration) if block_given?
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: github_org_manager
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brandon Weaver
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-02-
|
11
|
+
date: 2022-02-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: octokit
|