compulsive-forks 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/bin/compulsive-forks +128 -0
  3. metadata +60 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a74a5fe4bc64b55e3454ff21d6125ed55557e362
4
+ data.tar.gz: 1e3edf98f3eb1821987a964989cd88affd0a2493
5
+ SHA512:
6
+ metadata.gz: 9cb38ab4f47c9b348ea66b28a54fea46419b6ac4a53b97370fab17845f771cc65a24258fb88db468a4bc2deff9f4d3c606b9f32e73948624c44f0fb95553d905
7
+ data.tar.gz: 721a92132d6ce1a862afa81a58c2c0f6b8fc0daa3de3ef32b3f4037643617f889bfae05b50253c57933ab0fa9fff4df2ed7658e450f0ea5d7bdd30cddc02c309
@@ -0,0 +1,128 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'set'
5
+
6
+ require 'octokit'
7
+
8
+ options = { verbose: 0 }
9
+ OptionParser.new do |opts|
10
+ opts.banner = "Usage: #{__FILE__} [options]"
11
+
12
+ opts.on('-v', '--[no-]verbose', 'Run verbosely; use twice for more verbosity') do |v|
13
+ options[:verbose] += 1
14
+ end
15
+
16
+ opts.on('-t', '--token access_token', 'GitHub personal access token') do |t|
17
+ options[:access_token] = t
18
+ end
19
+
20
+ opts.on('-o', '--organization organization', 'An organization to run against') do |o|
21
+ options[:organization] = o
22
+ end
23
+ end.parse!
24
+
25
+ if options[:access_token].nil? || options[:access_token].empty?
26
+ $stderr.puts('Access token is required. Create one at https://github.com/settings/tokens/new')
27
+ $stderr.puts('Include the "repo" scope to include private repositories')
28
+ exit(1)
29
+ end
30
+
31
+ client = Octokit::Client.new(access_token: options[:access_token])
32
+ root = client.root
33
+
34
+ repos = if options[:organization]
35
+ if options[:verbose] >= 2
36
+ $stderr.puts "Fetching repos for #{options[:organization]}"
37
+ end
38
+ root.rels[:organization_repositories].get(uri: { org: options[:organization] })
39
+ else
40
+ if options[:verbose] >= 2
41
+ $stderr.puts 'Fetching your repos'
42
+ end
43
+ root.rels[:current_user_repositories].get(
44
+ query: { affiliation: 'owner', per_page: 100 }
45
+ )
46
+ end
47
+
48
+ loop do
49
+ repos.data.select(&:fork).each do |repo|
50
+ full = repo.rels[:self].get
51
+ parent = full.data.parent
52
+ if options[:verbose] >= 1
53
+ $stderr.puts "You forked #{repo.name} from #{full.data.parent.full_name}:"
54
+ end
55
+
56
+ shas = Set.new
57
+ delete = shas.method(:delete)
58
+
59
+ # Add our branches
60
+ sha_to_names = {}
61
+ if options[:verbose] >= 2
62
+ $stderr.puts 'Fetching branches'
63
+ end
64
+ branches = repo.rels[:branches].get(params: { per_page: 100 })
65
+ loop do
66
+ branches.data.each do |branch|
67
+ shas << branch.commit.sha
68
+ sha_to_names[branch.commit.sha] ||= []
69
+ sha_to_names[branch.commit.sha] << branch.name
70
+ end
71
+ break unless branches.rels[:next]
72
+ $stderr.puts 'Fetching next page of branches' if options[:verbose] >= 2
73
+ branches = branches.rels[:next].get
74
+ end
75
+ $stderr.puts " #{shas.length} SHAs to check" if options[:verbose] >= 1
76
+
77
+ if shas.length == 0
78
+ puts "https://github.com/#{repo.full_name}/settings"
79
+ next
80
+ end
81
+
82
+ # Delete parent branches tips
83
+ parent_branches = parent.rels[:branches].get(query: { per_page: 100 })
84
+ loop do
85
+ parent_branches.data.each.map(&:commit).map(&:sha).each(&delete)
86
+ break if parent_branches.rels[:next].nil? || shas.empty?
87
+ if options[:verbose] >= 2
88
+ $stderr.puts 'Fetching next page of parent branches'
89
+ end
90
+ parent_branches = parent_branches.rels[:next].get
91
+ end
92
+ if options[:verbose] >= 1
93
+ $stderr.puts " #{shas.length} SHAs after removing parent branch tips"
94
+ end
95
+
96
+ if shas.length == 0
97
+ puts "https://github.com/#{repo.full_name}/settings"
98
+ next
99
+ end
100
+
101
+ $stderr.puts 'Fetching commits' if options[:verbose] >= 2
102
+ commits = parent.rels[:commits].get(query: { per_page: 100 })
103
+ loop do
104
+ commits.data.map(&:sha).each(&delete)
105
+ break if commits.rels[:next].nil? || shas.empty?
106
+ $stderr.puts 'Fetching next page of commits' if options[:verbose] >= 2
107
+ commits = commits.rels[:next].get
108
+ end
109
+
110
+ if shas.length == 0
111
+ puts "https://github.com/#{repo.full_name}/settings"
112
+ next
113
+ end
114
+
115
+ if options[:verbose] >= 1
116
+ $stderr.puts " #{shas.length} not found in parent"
117
+ end
118
+
119
+ shas.each do |sha|
120
+ if options[:verbose] >= 1
121
+ $stderr.puts " -> #{sha} (#{sha_to_names[sha].join(', ')})"
122
+ end
123
+ end
124
+ end
125
+
126
+ break unless repos.rels[:next]
127
+ repos = repos.rels[:next].get
128
+ end
metadata ADDED
@@ -0,0 +1,60 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: compulsive-forks
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Benjamin Manns
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-04-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: octokit
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.0'
27
+ description:
28
+ email: benmanns@gmail.com
29
+ executables:
30
+ - compulsive-forks
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - bin/compulsive-forks
35
+ homepage: https://github.com/benmanns/compulsive-forks
36
+ licenses:
37
+ - MIT
38
+ metadata: {}
39
+ post_install_message:
40
+ rdoc_options: []
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ requirements: []
54
+ rubyforge_project:
55
+ rubygems_version: 2.6.8
56
+ signing_key:
57
+ specification_version: 4
58
+ summary: Finds the repos that you forked that can be safely deleted
59
+ test_files: []
60
+ has_rdoc: