github_org_manager 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|