git-forks 0.0.3 → 0.0.4

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.
Files changed (2) hide show
  1. data/lib/git-forks.rb +189 -55
  2. metadata +1 -1
@@ -11,7 +11,8 @@ require 'time'
11
11
 
12
12
  class GitForks
13
13
 
14
- CACHE_FILE = '.git/forks_cache.json'
14
+ CACHE_FILE = '.git/forks_cache.json'
15
+ NO_UPDATE_ACTIONS = ['help', 'usage', 'update', 'config']
15
16
 
16
17
  def initialize(args)
17
18
  @command = args.shift
@@ -30,7 +31,7 @@ class GitForks
30
31
  # If the cache file doesn't exist, make sure we run update
31
32
  # before any other command. git-forks will otherwise crash
32
33
  # with an exception.
33
- update unless File.exists?(CACHE_FILE) || @command == 'update'
34
+ update unless File.exists?(CACHE_FILE) || NO_UPDATE_ACTIONS.include?(@command)
34
35
 
35
36
  self.send @command
36
37
  elsif %w(-h --help).include?(@command)
@@ -62,6 +63,58 @@ class GitForks
62
63
  # Commands
63
64
  #-----------------------------------------------------------------------------
64
65
 
66
+ # list
67
+ # get
68
+ # add
69
+ # remove
70
+ #
71
+ def config
72
+ action = @args.shift
73
+ owner = @args.shift
74
+
75
+ if action
76
+ if owner || action == "list"
77
+ case action
78
+ when "list"
79
+ if (f = config_get_forks).size > 0
80
+ puts f
81
+ end
82
+ when "get"
83
+ if (v = config_get_fork(owner)).size > 0
84
+ puts v
85
+ end
86
+ when "add"
87
+ if config_get_fork(owner).size > 0
88
+ puts "#{owner} already exists."
89
+ else
90
+ config_add_fork(owner)
91
+ puts "Added #{owner}."
92
+ end
93
+ when "remove"
94
+ if config_get_fork(owner).empty?
95
+ puts "#{owner} not found."
96
+ else
97
+ # (Forces cache update.)
98
+ config_remove_fork(owner)
99
+ puts "Removed #{owner}."
100
+ end
101
+ else
102
+ puts "<action> '#{action}' unknown"
103
+ puts
104
+ usage
105
+ end
106
+ else
107
+ puts "<owner> argument missing"
108
+ puts
109
+ usage
110
+ end
111
+ else
112
+ puts "<action> argument missing"
113
+ puts
114
+ usage
115
+ end
116
+ end
117
+
65
118
  # Get the latest GitHub data.
66
119
  def update
67
120
  puts 'Retrieving the latest GitHub data...'
@@ -92,66 +145,82 @@ class GitForks
92
145
  def fetch
93
146
  target_owners = @args
94
147
 
95
- update if not @updated
148
+ update if not @updated # force cache update
149
+
150
+ cached_owners = []
96
151
  get_cached_data('forks').each do |fork|
97
- owner = fork['owner']['login']
98
- if target_owners.empty? or target_owners.include?(owner)
152
+ cached_owners << fork['owner']['login']
153
+ end
154
+
155
+ # fetch all configured forks by default
156
+ target_owners = cached_owners if target_owners.empty?
157
+
158
+ target_owners.each do |owner|
159
+ if cached_owners.include?(owner)
99
160
  puts '-' * 80
100
161
  puts "Fething Git data from fork '#{owner}/#{@repo}'"
101
- git("fetch #{github_endpoint}/#{owner}/#{@repo}.git " +
102
- "+refs/heads/*:refs/forks/#{owner}/*")
162
+ git_fetch_fork(owner)
163
+ else
164
+ # TODO: add --force => add owner to config automatically
165
+ puts '-' * 80
166
+ puts "'#{owner}/#{@repo}' is not in your forks whitelist."
167
+ puts
168
+ puts "Run: $ git forks config add #{owner}"
169
+ puts "and then try again, if you really want to pull from this fork."
170
+ puts
171
+ print "This is your current forks whitelist: "
172
+ if (f = config_get_forks).size > 0
173
+ puts f.gsub("\n", ', ')
174
+ else
175
+ puts "<empty>"
176
+ end
177
+ exit 1
103
178
  end
104
179
  end
105
180
  end
106
181
 
107
182
  # List all forks.
108
183
  #
109
- # Example::
110
- #
111
- # --------------------------------------------------------------------------------
112
- # Forks of 'doubleotoo/foo/master'
113
- #
114
- # Owner Branches Updated
115
- # ------ -------- -------
116
- # justintoo 2 01-May-12
117
- # rose-compiler 3 27-Apr-12
184
+ # TODO: add sorting by column
118
185
  #
119
186
  def list
120
187
  forks = get_cached_data('forks')
121
188
  forks.reverse! if @args.shift == '--reverse'
122
189
 
190
+ whitelist = config_get_forks.split("\n")
191
+
123
192
  output = forks.collect do |f|
193
+ owner = f['owner']['login']
194
+ whitelist.delete(owner)
195
+
124
196
  line = ""
125
- line << l(f['owner']['login'], 25)
197
+ line << l(owner, 25)
126
198
  line << l(f['branches'].size, 12)
127
199
  line << strftime(clean(f['updated_at']))
128
200
  end
129
201
 
130
202
  if output.compact.empty?
131
- puts "No forks of '#{@user}/#{@repo}'"
203
+ puts "No forks of '#{@user}/#{@repo}'."
132
204
  else
133
205
  puts '-' * 80
134
- puts "Forks of '#{@user}/#{@repo}'"
206
+ puts "Forks of '#{@user}/#{@repo}':"
135
207
  puts
136
208
  puts l('Owner', 25) + l('Branches', 12) + 'Updated'
137
209
  puts l('------', 25) + l('--------', 12) + '-------'
138
210
  puts output.compact
211
+ if whitelist.size > 0
212
+ whitelist.each do |f|
213
+ puts l(f, 25) + l('*', 12) + '*'
214
+ end
215
+
216
+ puts
217
+ puts '* no cache data available; may require `update`'
218
+ end
139
219
  puts '-' * 80
140
220
  end
141
221
  end
142
222
 
143
223
  # Show details of one fork.
144
- #
145
- # Example::
146
- #
147
- # -------------------------------------------------------------------------------
148
- # Owner : justintoo
149
- # Created : 01-May-12
150
- # Updated : 01-May-12
151
- # Branches : 2
152
- # 444a867d338cafc0c82d058b458b4fe268fa14d6 master
153
- # 14178fe5b204c38650de8ddaf5d9fb80aa834e74 foo
154
- #
155
224
  def show
156
225
  owner = @args.shift
157
226
  option = @args.shift
@@ -210,25 +279,43 @@ class GitForks
210
279
  end
211
280
 
212
281
  def help
213
- puts "No command: #{@command}"
214
- puts "Try: browse, fetch, list, show, update"
215
- puts "or call with '-h' for usage information"
282
+ puts "No command: #{@command}" if not @command == 'help'
283
+ puts "Try: browse, config, fetch, list, show, update;"
284
+ puts " or call with '-h' for usage information"
216
285
  end
217
286
 
218
287
  # Show a quick reference of available commands.
219
288
  def usage
220
- puts 'Usage: git forks <command>'
221
- puts 'Get GitHub project forks information.'
289
+ puts 'Usage: git forks [-h] <command>'
290
+ puts
291
+ puts 'Manage your GitHub project\'s forks.'
222
292
  puts
223
293
  puts 'Available commands:'
224
294
  puts ' browse <owner>[:<ref>] Show fork in web browser.'
225
295
  puts ' <ref> denotes a Git Tree or a Git Commit.'
226
- puts ' fetch <owners> git-fetch fork data from GitHub.'
296
+ puts ' config <action> [owner] Configure which forks you are interested in (all by default).'
297
+ puts
298
+ puts ' Available actions: '
299
+ puts ' list List all forks.'
300
+ puts ' get <owner> Check for <owner>.'
301
+ puts ' add <owner> Add <owner>.'
302
+ puts ' remove <owner> Remove <owner>. (Forces cache update.)'
303
+ puts
304
+ puts ' The associated git-ref data is also removed.'
305
+ puts
306
+ puts ' You may want to run `git gc --prune=now` to'
307
+ puts ' remove stale objects that you fetched from'
308
+ puts ' your forks. (Also, see git-reflog.)'
309
+ puts
310
+ puts ' You can run `git fsck` to list dangling objects.'
311
+ puts
312
+ puts ' (git-gc does have various default expiry times.)'
313
+ puts ' fetch [<owners>] git-fetch fork data from GitHub. (Forces cache update.)'
227
314
  puts ' <owners> is a space separate list.'
228
- puts ' (Forces cache update.)'
229
315
  puts ' list [--reverse] List all forks.'
230
316
  puts ' show <owner> Show details for a single fork.'
231
317
  puts ' update Retrieve fork info from GitHub API v3.'
318
+ puts ' usage Show this usage information.'
232
319
  end
233
320
 
234
321
  #-----------------------------------------------------------------------------
@@ -266,30 +353,16 @@ class GitForks
266
353
  #-----------------------------------------------------------------------------
267
354
 
268
355
  def fetch_fork_info
269
- forks = Octokit.forks("#{@user}/#{@repo}")
356
+ targets = config_get_forks # optional fork targets
357
+ forks = Octokit.forks("#{@user}/#{@repo}").select {|f|
358
+ targets.empty? or targets.include?(f.owner.login)
359
+ }
270
360
  end
271
361
 
272
362
  def fetch_fork_branches(fork_user)
273
363
  branches = Octokit.branches("#{fork_user}/#{@repo}")
274
364
  end
275
365
 
276
- #-----------------------------------------------------------------------------
277
- # Git
278
- #-----------------------------------------------------------------------------
279
-
280
- def git(command)
281
- `git #{command}`.chomp
282
- end
283
-
284
- def github_endpoint
285
- host = git("config --get-all github.host")
286
- if host.size > 0
287
- host
288
- else
289
- 'https://github.com'
290
- end
291
- end
292
-
293
366
  #-----------------------------------------------------------------------------
294
367
  # Display Helper Functions
295
368
  #-----------------------------------------------------------------------------
@@ -320,6 +393,10 @@ class GitForks
320
393
  end
321
394
  end
322
395
 
396
+ #-----------------------------------------------------------------------------
397
+ # Git
398
+ #-----------------------------------------------------------------------------
399
+
323
400
  #def github_login
324
401
  # git("config --get-all github.user")
325
402
  #end
@@ -362,4 +439,61 @@ class GitForks
362
439
  return nil, nil
363
440
  end
364
441
 
442
+ def git(command)
443
+ `git #{command}`.chomp
444
+ end
445
+
446
+ def github_endpoint
447
+ host = git("config --get-all github.host")
448
+ if host.size > 0
449
+ host
450
+ else
451
+ 'https://github.com'
452
+ end
453
+ end
454
+
455
+ def config_get_forks
456
+ git("config --get-all github.forks.owner")
457
+ end
458
+
459
+ def config_get_fork(owner)
460
+ git("config --get-all github.forks.owner \"^#{owner}$\"")
461
+ end
462
+
463
+ def config_add_fork(owner)
464
+ git("config --add github.forks.owner #{owner}")
465
+ end
466
+
467
+ # (Forces cache update.)
468
+ def config_remove_fork(owner)
469
+ git("config --unset github.forks.owner \"^#{owner}$\"")
470
+ git_remove_fork(owner)
471
+ update # TODO: optimize by only updating if fork existed
472
+ end
473
+
474
+ # Remove a fork's git-refs.
475
+ #
476
+ # Directory: refs/forks/rose-compiler/ <-- notice the trailing slash
477
+ # Single: refs/forks/rose-compiler/master
478
+ def git_remove_fork(owner)
479
+ refdir = "refs/forks/#{owner}"
480
+ gitdir = ".git/#{refdir}"
481
+
482
+ if Dir.exists?(gitdir)
483
+ Dir.foreach(gitdir) do |ref|
484
+ next if ref == '.' or ref == '..'
485
+ # delete each individual ref
486
+ git("update-ref -d #{refdir}/#{ref}")
487
+ end
488
+
489
+ # delete the ref directory
490
+ git("update-ref -d #{refdir}")
491
+ end
492
+ end
493
+
494
+ def git_fetch_fork(owner)
495
+ git("fetch --prune " +
496
+ "#{github_endpoint}/#{owner}/#{@repo}.git " +
497
+ "+refs/heads/*:refs/forks/#{owner}/*")
498
+ end
365
499
  end # GitForks
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git-forks
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors: