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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f040bda13816a4be56c79705bfc08b8ddc4103b912b0739f995fd39c8b9b4762
4
- data.tar.gz: bfbc002654df01530548f3bbbf992d3b174ef7926729e1e08b4118627be24665
3
+ metadata.gz: 448927c5116bc5a19aa7eb3ede1e38fbf835014d385f1b3060958c18b72fb72d
4
+ data.tar.gz: dbae6b024e64729cefb7c424c8c994989ce40deeeab2a111fc457a2108d45fe7
5
5
  SHA512:
6
- metadata.gz: 95727ac38a7088d1e3751af1f25b5c824376a1e84ce8235b1c21658bbab373133952ed84142ea082f6b6db78e087d2f7382f8b6ae021932215075b0efbb7f400
7
- data.tar.gz: e94d42b5257c15ad21b7d2ef59f81f3b45f7f8ae41866864100c6964f6ca7db3e2105e20c4a3d527d4f90ec56ae1a61ee6bb44fc8777f563fcf217e651bdf2a1
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
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- github_org_manager (0.0.1)
4
+ github_org_manager (0.0.2)
5
5
  netrc (~> 0.11.0)
6
6
  octokit (~> 4.22.0)
7
7
 
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
- $ bundle install
54
+ ```sh
55
+ $ bundle install
56
+ ```
49
57
 
50
58
  Or install it yourself as:
51
59
 
52
- $ gem install github_org_manager
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/[USERNAME]/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/[USERNAME]/github_org_manager/blob/main/CODE_OF_CONDUCT.md).
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
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GithubOrgManager
4
- VERSION = "0.0.2"
4
+ VERSION = "0.0.3"
5
5
  end
@@ -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 :dev_home, :org_name, :repos, :repo_paths
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(path_name, org_name)
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
- @client = client(octokit_params:, &octokit_configuration)
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
- @repos = @client.org_repos(@org_name).to_h do |repo_data|
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
- @repo_paths = @repos.to_h do |repo_name, _repo_url|
54
- [repo_name, File.join(@org_path, repo_name)]
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
- @repos.each do |name, html_url|
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 #{@repo_paths.size} repos: \n"
185
+ puts "📦 Updating #{repo_paths.size} repos: \n"
79
186
 
80
- @repo_paths.each do |name, path|
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
- def client(octokit_params:, &configuration)
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.2
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-17 00:00:00.000000000 Z
11
+ date: 2022-02-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: octokit