git-forks 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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: