tekkub-github 0.3.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.
@@ -0,0 +1,113 @@
1
+ desc "Project network tools - sub-commands : web [user], list, fetch, commits"
2
+ flags :after => "Only show commits after a certain date"
3
+ flags :before => "Only show commits before a certain date"
4
+ flags :shas => "Only show shas"
5
+ flags :project => "Filter commits on a certain project"
6
+ flags :author => "Filter commits on a email address of author"
7
+ flags :applies => "Filter commits to patches that apply cleanly"
8
+ flags :noapply => "Filter commits to patches that do not apply cleanly"
9
+ flags :nocache => "Do not use the cached network data"
10
+ flags :cache => "Use the network data even if it's expired"
11
+ flags :sort => "How to sort : date(*), branch, author"
12
+ flags :common => "Show common branch point"
13
+ flags :thisbranch => "Look at branches that match the current one"
14
+ flags :limit => "Only look through the first X heads - useful for really large projects"
15
+ command :network do |command, user|
16
+ return if !helper.project
17
+ user ||= helper.owner
18
+
19
+ case command
20
+ when 'web'
21
+ helper.open helper.network_page_for(user)
22
+ when 'list'
23
+ data = helper.get_network_data(user, options)
24
+ data['users'].each do |hsh|
25
+ puts [ hsh['name'].ljust(20), hsh['heads'].map {|a| a['name']}.uniq.join(', ') ].join(' ')
26
+ end
27
+ when 'fetch'
28
+ # fetch each remote we don't have
29
+ data = helper.get_network_data(user, options)
30
+ data['users'].each do |hsh|
31
+ u = hsh['name']
32
+ GitHub.invoke(:track, u) unless helper.tracking?(u)
33
+ puts "fetching #{u}"
34
+ GitHub.invoke(:fetch_all, u)
35
+ end
36
+ when 'commits'
37
+ # show commits we don't have yet
38
+
39
+ $stderr.puts 'gathering heads'
40
+ cherry = []
41
+
42
+ if helper.cache_commits_data(options)
43
+ ids = []
44
+ data = helper.get_network_data(user, options)
45
+ data['users'].each do |hsh|
46
+ u = hsh['name']
47
+ if options[:thisbranch]
48
+ user_ids = hsh['heads'].map { |a| a['id'] if a['name'] == helper.current_branch }.compact
49
+ else
50
+ user_ids = hsh['heads'].map { |a| a['id'] }
51
+ end
52
+ user_ids.each do |id|
53
+ if !helper.has_commit?(id) && helper.cache_expired?
54
+ GitHub.invoke(:track, u) unless helper.tracking?(u)
55
+ puts "fetching #{u}"
56
+ GitHub.invoke(:fetch_all, u)
57
+ end
58
+ end
59
+ ids += user_ids
60
+ end
61
+ ids.uniq!
62
+
63
+ $stderr.puts 'has heads'
64
+
65
+ # check that we have all these shas locally
66
+ local_heads = helper.local_heads
67
+ local_heads_not = local_heads.map { |a| "^#{a}"}
68
+ looking_for = (ids - local_heads) + local_heads_not
69
+ commits = helper.get_commits(looking_for)
70
+
71
+ $stderr.puts 'ID SIZE:' + ids.size.to_s
72
+
73
+ ignores = helper.ignore_sha_array
74
+
75
+ ids.each do |id|
76
+ next if ignores[id] || !commits.assoc(id)
77
+ cherries = helper.get_cherry(id)
78
+ cherries = helper.remove_ignored(cherries, ignores)
79
+ cherry += cherries
80
+ helper.ignore_shas([id]) if cherries.size == 0
81
+ $stderr.puts "checking head #{id} : #{cherry.size.to_s}"
82
+ break if options[:limit] && cherry.size > options[:limit].to_i
83
+ end
84
+ end
85
+
86
+ if cherry.size > 0 || !helper.cache_commits_data(options)
87
+ helper.print_network_cherry_help if !options[:shas]
88
+
89
+ if helper.cache_commits_data(options)
90
+ $stderr.puts "caching..."
91
+ $stderr.puts "commits: " + cherry.size.to_s
92
+ our_commits = cherry.map { |item| c = commits.assoc(item[1]); [item, c] if c }
93
+ our_commits.delete_if { |item| item == nil }
94
+ helper.cache_commits(our_commits)
95
+ else
96
+ $stderr.puts "using cached..."
97
+ our_commits = helper.commits_cache
98
+ end
99
+
100
+ helper.print_commits(our_commits, options)
101
+ else
102
+ puts "no unapplied commits"
103
+ end
104
+ else
105
+ helper.print_network_help
106
+ end
107
+ end
108
+
109
+ desc "Ignore a SHA (from 'github network commits')"
110
+ command :ignore do |sha|
111
+ commits = helper.resolve_commits(sha)
112
+ helper.ignore_shas(commits) # add to .git/ignore-shas file
113
+ end
@@ -0,0 +1,26 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "github"
3
+ s.version = "0.3.3"
4
+
5
+ s.specification_version = 2 if s.respond_to? :specification_version=
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Chris Wanstrath, Kevin Ballard, Scott Chacon"]
9
+ s.date = %q{2008-05-18}
10
+ s.default_executable = %q{gh}
11
+ s.description = %q{The official `github` command line helper for simplifying your GitHub experience.}
12
+ s.email = %q{chris@ozmm.org}
13
+ s.executables = ["github", "gh"]
14
+ s.extra_rdoc_files = ["bin/github", "bin/gh", "lib/github/extensions.rb", "lib/github/command.rb", "lib/github/helper.rb", "lib/github.rb", "LICENSE", "README"]
15
+ s.files = ["bin/github", "commands/network.rb", "commands/commands.rb", "commands/helpers.rb", "lib/github/extensions.rb", "lib/github/command.rb", "lib/github/helper.rb", "lib/github.rb", "LICENSE", "Manifest", "README", "spec/command_spec.rb", "spec/extensions_spec.rb", "spec/github_spec.rb", "spec/helper_spec.rb", "spec/spec_helper.rb", "spec/ui_spec.rb", "spec/windoze_spec.rb", "github-gem.gemspec"]
16
+ s.has_rdoc = true
17
+ s.homepage = %q{http://github.com/}
18
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Github", "--main", "README"]
19
+ s.require_paths = ["lib"]
20
+ s.rubyforge_project = %q{github}
21
+ s.rubygems_version = %q{1.1.1}
22
+ s.summary = %q{The official `github` command line helper for simplifying your GitHub experience.}
23
+
24
+ # s.add_dependency(%q<launchy>, [">= 0"])
25
+ s.add_dependency('json_pure', [">= 0"])
26
+ end
@@ -0,0 +1,172 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+ require 'github/extensions'
3
+ require 'github/command'
4
+ require 'github/helper'
5
+ require 'fileutils'
6
+ require 'rubygems'
7
+ require 'open-uri'
8
+ require 'json'
9
+ require 'yaml'
10
+
11
+ ##
12
+ # Starting simple.
13
+ #
14
+ # $ github <command> <args>
15
+ #
16
+ # GitHub.command <command> do |*args|
17
+ # whatever
18
+ # end
19
+ #
20
+
21
+ module GitHub
22
+ extend self
23
+
24
+ BasePath = File.expand_path(File.dirname(__FILE__) + '/..')
25
+
26
+ def command(command, options = {}, &block)
27
+ debug "Registered `#{command}`"
28
+ descriptions[command] = @next_description if @next_description
29
+ @next_description = nil
30
+ flag_descriptions[command].update @next_flags if @next_flags
31
+ usage_descriptions[command] = @next_usage if @next_usage
32
+ @next_flags = nil
33
+ @next_usage = []
34
+ commands[command.to_s] = Command.new(block)
35
+ Array(options[:alias] || options[:aliases]).each do |command_alias|
36
+ commands[command_alias.to_s] = commands[command.to_s]
37
+ end
38
+ end
39
+
40
+ def desc(str)
41
+ @next_description = str
42
+ end
43
+
44
+ def flags(hash)
45
+ @next_flags ||= {}
46
+ @next_flags.update hash
47
+ end
48
+
49
+ def usage(string)
50
+ @next_usage ||= []
51
+ @next_usage << string
52
+ end
53
+
54
+ def helper(command, &block)
55
+ debug "Helper'd `#{command}`"
56
+ Helper.send :define_method, command, &block
57
+ end
58
+
59
+ def activate(args)
60
+ @@original_args = args.clone
61
+ @options = parse_options(args)
62
+ @debug = @options.delete(:debug)
63
+ @learn = @options.delete(:learn)
64
+ Dir[BasePath + '/commands/*.rb'].each do |command|
65
+ load command
66
+ end
67
+ invoke(args.shift, *args)
68
+ end
69
+
70
+ def invoke(command, *args)
71
+ block = find_command(command)
72
+ debug "Invoking `#{command}`"
73
+ block.call(*args)
74
+ end
75
+
76
+ def find_command(name)
77
+ name = name.to_s
78
+ commands[name] || GitCommand.new(name) || commands['default']
79
+ end
80
+
81
+ def commands
82
+ @commands ||= {}
83
+ end
84
+
85
+ def descriptions
86
+ @descriptions ||= {}
87
+ end
88
+
89
+ def flag_descriptions
90
+ @flagdescs ||= Hash.new { |h, k| h[k] = {} }
91
+ end
92
+
93
+ def usage_descriptions
94
+ @usage_descriptions ||= Hash.new { |h, k| h[k] = [] }
95
+ end
96
+
97
+ def options
98
+ @options
99
+ end
100
+
101
+ def original_args
102
+ @@original_args ||= []
103
+ end
104
+
105
+ def parse_options(args)
106
+ idx = 0
107
+ args.clone.inject({}) do |memo, arg|
108
+ case arg
109
+ when /^--(.+?)=(.*)/
110
+ args.delete_at(idx)
111
+ memo.merge($1.to_sym => $2)
112
+ when /^--(.+)/
113
+ args.delete_at(idx)
114
+ memo.merge($1.to_sym => true)
115
+ when "--"
116
+ args.delete_at(idx)
117
+ return memo
118
+ else
119
+ idx += 1
120
+ memo
121
+ end
122
+ end
123
+ end
124
+
125
+ def debug(*messages)
126
+ puts *messages.map { |m| "== #{m}" } if debug?
127
+ end
128
+
129
+ def learn(message)
130
+ if learn?
131
+ puts "== " + Color.yellow(message)
132
+ else
133
+ debug(message)
134
+ end
135
+ end
136
+
137
+ def learn?
138
+ !!@learn
139
+ end
140
+
141
+ def debug?
142
+ !!@debug
143
+ end
144
+
145
+ def load(file)
146
+ file[0] == ?/ ? path = file : path = BasePath + "/commands/#{File.basename(file)}"
147
+ data = File.read(path)
148
+ GitHub.module_eval data, path
149
+ end
150
+ end
151
+
152
+ GitHub.command :default, :aliases => ['', '-h', 'help', '-help', '--help'] do
153
+ puts "Usage: github command <space separated arguments>", ''
154
+ puts "Available commands:", ''
155
+ longest = GitHub.descriptions.map { |d,| d.to_s.size }.max
156
+ GitHub.descriptions.sort {|a,b| a.to_s <=> b.to_s }.each do |command, desc|
157
+ cmdstr = "%-#{longest}s" % command
158
+ puts " #{cmdstr} => #{desc}"
159
+ flongest = GitHub.flag_descriptions[command].map { |d,| "--#{d}".size }.max
160
+ GitHub.usage_descriptions[command].each do |usage_descriptions|
161
+ usage_descriptions.each do |usage|
162
+ usage_str = "#{" " * longest} %% %-#{flongest}s" % usage
163
+ puts usage_str
164
+ end
165
+ end
166
+ GitHub.flag_descriptions[command].each do |flag, fdesc|
167
+ flagstr = "#{" " * longest} %-#{flongest}s" % "--#{flag}"
168
+ puts " #{flagstr}: #{fdesc}"
169
+ end
170
+ end
171
+ puts
172
+ end
@@ -0,0 +1,121 @@
1
+ if RUBY_PLATFORM =~ /mswin|mingw/
2
+ begin
3
+ require 'win32/open3'
4
+ rescue LoadError
5
+ warn "You must 'gem install win32-open3' to use the github command on Windows"
6
+ exit 1
7
+ end
8
+ else
9
+ require 'open3'
10
+ end
11
+
12
+ module GitHub
13
+ class Command
14
+ def initialize(block)
15
+ (class << self;self end).send :define_method, :command, &block
16
+ end
17
+
18
+ def call(*args)
19
+ arity = method(:command).arity
20
+ args << nil while args.size < arity
21
+ send :command, *args
22
+ end
23
+
24
+ def helper
25
+ @helper ||= Helper.new
26
+ end
27
+
28
+ def options
29
+ GitHub.options
30
+ end
31
+
32
+ def pgit(*command)
33
+ puts git(*command)
34
+ end
35
+
36
+ def git(command)
37
+ run :sh, command
38
+ end
39
+
40
+ def git_exec(command)
41
+ run :exec, command
42
+ end
43
+
44
+ def run(method, command)
45
+ if command.is_a? Array
46
+ command = [ 'git', command ].flatten
47
+ GitHub.learn command.join(' ')
48
+ else
49
+ command = 'git ' + command
50
+ GitHub.learn command
51
+ end
52
+
53
+ send method, *command
54
+ end
55
+
56
+ def sh(*command)
57
+ Shell.new(*command).run
58
+ end
59
+
60
+ def die(message)
61
+ puts "=> #{message}"
62
+ exit!
63
+ end
64
+
65
+ def github_user
66
+ git("config --get github.user")
67
+ end
68
+
69
+ def shell_user
70
+ ENV['USER']
71
+ end
72
+
73
+ def current_user?(user)
74
+ user == github_user || user == shell_user
75
+ end
76
+
77
+ class Shell < String
78
+ attr_reader :error
79
+ attr_reader :out
80
+
81
+ def initialize(*command)
82
+ @command = command
83
+ end
84
+
85
+ def run
86
+ GitHub.debug "sh: #{command}"
87
+ _, out, err = Open3.popen3(*@command)
88
+
89
+ out = out.read.strip
90
+ err = err.read.strip
91
+
92
+ replace @error = err if err.any?
93
+ replace @out = out if out.any?
94
+
95
+ self
96
+ end
97
+
98
+ def command
99
+ @command.join(' ')
100
+ end
101
+
102
+ def error?
103
+ !!@error
104
+ end
105
+
106
+ def out?
107
+ !!@out
108
+ end
109
+ end
110
+ end
111
+
112
+ class GitCommand < Command
113
+ def initialize(name)
114
+ @name = name
115
+ end
116
+
117
+ def command(*args)
118
+ git_exec [ @name, args ]
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,39 @@
1
+ # define #try
2
+ class Object
3
+ def try
4
+ self
5
+ end
6
+ end
7
+
8
+ class NilClass
9
+ klass = Class.new
10
+ klass.class_eval do
11
+ instance_methods.each { |meth| undef_method meth.to_sym unless meth =~ /^__(id|send)__$/ }
12
+ def method_missing(*args)
13
+ self
14
+ end
15
+ end
16
+ NilProxy = klass.new
17
+ def try
18
+ NilProxy
19
+ end
20
+ end
21
+
22
+ # define #tap
23
+ class Object
24
+ def tap(&block)
25
+ block.call(self)
26
+ self
27
+ end
28
+ end
29
+
30
+ # cute
31
+ module Color
32
+ COLORS = { :clear => 0, :red => 31, :green => 32, :yellow => 33 }
33
+ def self.method_missing(color_name, *args)
34
+ color(color_name) + args.first + color(:clear)
35
+ end
36
+ def self.color(color)
37
+ "\e[#{COLORS[color.to_sym]}m"
38
+ end
39
+ end