github 0.1.1 → 0.4.0

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 (47) hide show
  1. data/History.txt +37 -0
  2. data/Manifest +33 -12
  3. data/README.md +187 -0
  4. data/Rakefile +44 -0
  5. data/bin/gh +8 -0
  6. data/bin/github +4 -1
  7. data/github.gemspec +29 -34
  8. data/lib/commands/commands.rb +249 -0
  9. data/lib/commands/helpers.rb +486 -0
  10. data/lib/commands/issues.rb +17 -0
  11. data/lib/commands/network.rb +110 -0
  12. data/lib/github.rb +117 -29
  13. data/lib/github/command.rb +69 -14
  14. data/lib/github/extensions.rb +39 -0
  15. data/lib/github/ui.rb +19 -0
  16. data/setup.rb +1551 -0
  17. data/spec/command_spec.rb +82 -0
  18. data/spec/commands/command_browse_spec.rb +36 -0
  19. data/spec/commands/command_clone_spec.rb +87 -0
  20. data/spec/commands/command_create-from-local_spec.rb +7 -0
  21. data/spec/commands/command_fetch_spec.rb +56 -0
  22. data/spec/commands/command_fork_spec.rb +44 -0
  23. data/spec/commands/command_helper.rb +170 -0
  24. data/spec/commands/command_home_spec.rb +20 -0
  25. data/spec/commands/command_info_spec.rb +23 -0
  26. data/spec/commands/command_issues_spec.rb +97 -0
  27. data/spec/commands/command_network_spec.rb +30 -0
  28. data/spec/commands/command_pull-request_spec.rb +51 -0
  29. data/spec/commands/command_pull_spec.rb +82 -0
  30. data/spec/commands/command_search_spec.rb +34 -0
  31. data/spec/commands/command_track_spec.rb +82 -0
  32. data/spec/commands_spec.rb +49 -0
  33. data/spec/extensions_spec.rb +36 -0
  34. data/spec/github_spec.rb +85 -0
  35. data/spec/helper_spec.rb +368 -0
  36. data/spec/spec_helper.rb +160 -4
  37. data/spec/windoze_spec.rb +38 -0
  38. metadata +114 -47
  39. data/README +0 -49
  40. data/commands/commands.rb +0 -54
  41. data/commands/helpers.rb +0 -79
  42. data/spec/helpers/owner_spec.rb +0 -12
  43. data/spec/helpers/project_spec.rb +0 -12
  44. data/spec/helpers/public_url_for_spec.rb +0 -12
  45. data/spec/helpers/repo_for_spec.rb +0 -12
  46. data/spec/helpers/user_and_repo_from_spec.rb +0 -15
  47. data/spec/helpers/user_for_spec.rb +0 -12
@@ -0,0 +1,20 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require File.dirname(__FILE__) + '/command_helper'
3
+
4
+ describe "github home" do
5
+ include CommandHelper
6
+
7
+ specify "home should open the project home page" do
8
+ running :home do
9
+ setup_url_for
10
+ @helper.should_receive(:open).once.with("https://github.com/user/project/tree/master")
11
+ end
12
+ end
13
+
14
+ specify "home defunkt should open the home page of defunkt's fork" do
15
+ running :home, "defunkt" do
16
+ setup_url_for
17
+ @helper.should_receive(:open).once.with("https://github.com/defunkt/project/tree/master")
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,23 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require File.dirname(__FILE__) + '/command_helper'
3
+
4
+ describe "github info" do
5
+ include CommandHelper
6
+
7
+ specify "info should show info for this project" do
8
+ running :info do
9
+ setup_url_for
10
+ setup_remote(:origin, :user => "user", :ssh => true)
11
+ setup_remote(:defunkt)
12
+ setup_remote(:external, :url => "home:/path/to/project.git")
13
+ stdout.should == <<-EOF
14
+ == Info for project
15
+ You are user
16
+ Currently tracking:
17
+ - defunkt (as defunkt)
18
+ - home:/path/to/project.git (as external)
19
+ - user (as origin)
20
+ EOF
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,97 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require File.dirname(__FILE__) + '/command_helper'
3
+
4
+ describe "github issues" do
5
+ include CommandHelper
6
+
7
+ specify "issues without args should show help" do
8
+ running :issues do
9
+ setup_url_for
10
+ stdout.should == <<-EOS.gsub(/^ /, '')
11
+ You have to provide a command :
12
+
13
+ open - shows open tickets for this project
14
+ closed - shows closed tickets for this project
15
+
16
+ --user=<username> - show issues from <username>'s repository
17
+ --after=<date> - only show issues updated after <date>
18
+
19
+ EOS
20
+ end
21
+ end
22
+
23
+ specify "issues web opens the project's issues page" do
24
+ running :issues, "open" do
25
+ setup_url_for
26
+ mock_issues_for "open"
27
+ stdout.should == <<-EOS.gsub(/^ /, '')
28
+ -----
29
+ Issue #1 (0 votes): members.json 500 error
30
+ * Opened about 10 hours ago by bug_finder
31
+ * Last updated 5 minutes ago
32
+
33
+ I have a nasty bug.
34
+ -----
35
+ EOS
36
+ end
37
+ end
38
+
39
+ specify "issues web closed the project's issues page" do
40
+ running :issues, "closed" do
41
+ setup_url_for
42
+ mock_issues_for "closed"
43
+ stdout.should == <<-EOS.gsub(/^ /, '')
44
+ -----
45
+ Issue #1 (0 votes): members.json 500 error
46
+ * Opened about 10 hours ago by bug_finder
47
+ * Closed 5 minutes ago
48
+ * Last updated 5 minutes ago
49
+
50
+ I have a nasty bug.
51
+ -----
52
+ EOS
53
+ end
54
+ end
55
+
56
+ specify "issues web opens the project's issues page" do
57
+ running :issues, "web" do
58
+ setup_url_for
59
+ @helper.should_receive(:open).once.with("https://github.com/user/project/issues")
60
+ end
61
+ end
62
+
63
+ specify "issues web <user> opens the project's issues page for a user repo" do
64
+ running :issues, "web", "drnic" do
65
+ setup_url_for
66
+ @helper.should_receive(:open).once.with("https://github.com/drnic/project/issues")
67
+ end
68
+ end
69
+
70
+ class CommandHelper::Runner
71
+ def mock_issues_for(state = "open", options = {})
72
+ options[:updated_at] = 5.minutes.ago
73
+ options[:closed_at] = 5.minutes.ago
74
+ options[:created_at] = 10.hours.ago
75
+ options[:user] = "user"
76
+ options[:project] = "project"
77
+ yaml = <<-YAML.gsub(/^ /, '')
78
+ ---
79
+ issues:
80
+ - number: 1
81
+ votes: 0
82
+ created_at: #{options[:created_at].strftime("%Y-%m-%d %H:%M:%S %z")}
83
+ body: |-
84
+ I have a nasty bug.
85
+ title: members.json 500 error
86
+ updated_at: #{options[:updated_at].strftime("%Y-%m-%d %H:%M:%S %z")}
87
+ #{"closed_at: #{options[:closed_at].strftime("%Y-%m-%d %H:%M:%S %z")}" if state == "closed"}
88
+ user: bug_finder
89
+ labels: []
90
+
91
+ state: #{state}
92
+ YAML
93
+ api_url = "http://github.com/api/v2/yaml/issues/list/#{options[:user]}/#{options[:project]}/#{state}"
94
+ @command.should_receive(:open).with(api_url).and_return(yaml)
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,30 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require File.dirname(__FILE__) + '/command_helper'
3
+
4
+ describe "github network" do
5
+ include CommandHelper
6
+
7
+ specify "network list should show all users with a fork" do
8
+ running :network, 'list' do
9
+ setup_url_for 'origin', 'drnic'
10
+ users = %w[defunkt drnic _why]
11
+ @helper.should_receive(:network_members).with('drnic', {}).and_return(users)
12
+ stdout.should == "defunkt\ndrnic\n_why\n"
13
+ end
14
+ end
15
+
16
+ specify "network should open the network page for this repo" do
17
+ running :network, 'web' do
18
+ setup_url_for
19
+ @helper.should_receive(:open).once.with("https://github.com/user/project/network")
20
+ end
21
+ end
22
+
23
+ specify "network defunkt should open the network page for defunkt's fork" do
24
+ running :network, 'web', "defunkt" do
25
+ setup_url_for
26
+ @helper.should_receive(:open).once.with("https://github.com/defunkt/project/network")
27
+ end
28
+ end
29
+
30
+ end
@@ -0,0 +1,51 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require File.dirname(__FILE__) + '/command_helper'
3
+
4
+ describe "github pull-request" do
5
+ include CommandHelper
6
+
7
+ specify "pull-request should die with no args" do
8
+ running :'pull-request' do
9
+ setup_url_for
10
+ @command.should_receive(:die).with("Specify a user for the pull request").and_return { raise "Died" }
11
+ self.should raise_error(RuntimeError)
12
+ end
13
+ end
14
+
15
+ specify "pull-request user should track user if untracked" do
16
+ running :'pull-request', "user" do
17
+ setup_url_for
18
+ setup_remote :origin, :user => "kballard"
19
+ setup_remote :defunkt
20
+ GitHub.should_receive(:invoke).with(:track, "user").and_return { raise "Tracked" }
21
+ self.should raise_error("Tracked")
22
+ end
23
+ end
24
+
25
+ specify "pull-request user/branch should generate a pull request" do
26
+ running :'pull-request', "user/branch" do
27
+ setup_url_for
28
+ setup_remote :origin, :user => "kballard"
29
+ setup_remote :user
30
+ @command.should_receive(:git_exec).with("request-pull user/branch origin")
31
+ end
32
+ end
33
+
34
+ specify "pull-request user should generate a pull request with branch master" do
35
+ running :'pull-request', "user" do
36
+ setup_url_for
37
+ setup_remote :origin, :user => "kballard"
38
+ setup_remote :user
39
+ @command.should_receive(:git_exec).with("request-pull user/master origin")
40
+ end
41
+ end
42
+
43
+ specify "pull-request user branch should generate a pull request" do
44
+ running:'pull-request', "user", "branch" do
45
+ setup_url_for
46
+ setup_remote :origin, :user => "kballard"
47
+ setup_remote :user
48
+ @command.should_receive(:git_exec).with("request-pull user/branch origin")
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,82 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require File.dirname(__FILE__) + '/command_helper'
3
+
4
+ describe "github pull" do
5
+ include CommandHelper
6
+
7
+ specify "pull defunkt should start tracking defunkt if they're not already tracked" do
8
+ running :pull, "defunkt" do
9
+ mock_members 'defunkt'
10
+ setup_remote(:origin, :user => "user", :ssh => true)
11
+ setup_remote(:external, :url => "home:/path/to/project.git")
12
+ GitHub.should_receive(:invoke).with(:track, "defunkt").and_return { raise "Tracked" }
13
+ self.should raise_error("Tracked")
14
+ end
15
+ end
16
+
17
+ specify "pull defunkt should create defunkt/master and pull from the defunkt remote" do
18
+ running :pull, "defunkt" do
19
+ mock_members 'defunkt'
20
+ setup_remote(:defunkt)
21
+ @helper.should_receive(:branch_dirty?).and_return false
22
+ @command.should_receive(:git).with("fetch defunkt").ordered
23
+ @command.should_receive(:git_exec).with("checkout -b defunkt/master defunkt/master").ordered
24
+ stdout.should == "Switching to defunkt-master\n"
25
+ end
26
+ end
27
+
28
+ specify "pull defunkt should switch to pre-existing defunkt/master and pull from the defunkt remote" do
29
+ running :pull, "defunkt" do
30
+ mock_members 'defunkt'
31
+ setup_remote(:defunkt)
32
+ @helper.should_receive(:branch_dirty?).and_return true
33
+ @command.should_receive(:die).with("Unable to switch branches, your current branch has uncommitted changes").and_return { raise "Died" }
34
+ self.should raise_error(RuntimeError)
35
+ end
36
+ end
37
+
38
+ specify "pull defunkt wip should create defunkt/wip and pull from wip branch on defunkt remote" do
39
+ running :pull, "defunkt", "wip" do
40
+ mock_members 'defunkt'
41
+ setup_remote(:defunkt)
42
+ @helper.should_receive(:branch_dirty?).and_return true
43
+ @command.should_receive(:die).with("Unable to switch branches, your current branch has uncommitted changes").and_return { raise "Died" }
44
+ self.should raise_error(RuntimeError)
45
+ end
46
+ end
47
+
48
+ specify "pull defunkt/wip should switch to pre-existing defunkt/wip and pull from wip branch on defunkt remote" do
49
+ running :pull, "defunkt/wip" do
50
+ mock_members 'defunkt'
51
+ setup_remote(:defunkt)
52
+ @helper.should_receive(:branch_dirty?).and_return false
53
+ @command.should_receive(:git).with("fetch defunkt").ordered
54
+ @command.should_receive(:git_exec).with("checkout -b defunkt/wip defunkt/wip").ordered
55
+ stdout.should == "Switching to defunkt-wip\n"
56
+ end
57
+ end
58
+
59
+ specify "pull --merge defunkt should pull from defunkt remote into current branch" do
60
+ running :pull, "--merge", "defunkt" do
61
+ mock_members 'defunkt'
62
+ setup_remote(:defunkt)
63
+ @helper.should_receive(:branch_dirty?).and_return false
64
+ @command.should_receive(:git_exec).with("pull defunkt master")
65
+ end
66
+ end
67
+
68
+ specify "pull falls through for non-recognized commands" do
69
+ running :pull, 'remote' do
70
+ mock_members 'defunkt'
71
+ setup_remote(:defunkt)
72
+ @command.should_receive(:git_exec).with("pull remote")
73
+ end
74
+ end
75
+
76
+ specify "pull passes along args when falling through" do
77
+ running :pull, 'remote', '--stat' do
78
+ mock_members 'defunkt'
79
+ @command.should_receive(:git_exec).with("pull remote --stat")
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,34 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require File.dirname(__FILE__) + '/command_helper'
3
+
4
+ describe "github search" do
5
+ include CommandHelper
6
+
7
+ specify "search finds multiple results" do
8
+ running :search, "github-gem" do
9
+ json = StringIO.new '{"repositories":[' +
10
+ '{"name":"github-gem","size":300,"followers":499,"username":"defunkt","language":"Ruby","fork":false,"id":"repo-1653","type":"repo","pushed":"2008-12-04T03:14:00Z","forks":59,"description":"The official `github` command line helper for simplifying your GitHub experience.","score":3.4152448,"created":"2008-02-28T09:35:34Z"},' +
11
+ '{"name":"github-gem-builder","size":76,"followers":26,"username":"pjhyett","language":"Ruby","fork":false,"id":"repo-67489","type":"repo","pushed":"2008-11-04T04:54:57Z","forks":3,"description":"The scripts used to build RubyGems on GitHub","score":3.4152448,"created":"2008-10-24T22:29:32Z"}' +
12
+ ']}'
13
+ json.rewind
14
+ @command.should_receive(:open).with("http://github.com/api/v1/json/search/github-gem").and_return(json)
15
+ stdout.should == "defunkt/github-gem\npjhyett/github-gem-builder\n"
16
+ end
17
+ end
18
+
19
+ specify "search finds no results" do
20
+ running :search, "xxxxxxxxxx" do
21
+ json = StringIO.new '{"repositories":[]}'
22
+ json.rewind
23
+ @command.should_receive(:open).with("http://github.com/api/v1/json/search/xxxxxxxxxx").and_return(json)
24
+ stdout.should == "No results found\n"
25
+ end
26
+ end
27
+
28
+ specify "search shows usage if no arguments given" do
29
+ running :search do
30
+ @command.should_receive(:die).with("Usage: github search [query]").and_return { raise "Died" }
31
+ self.should raise_error(RuntimeError)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,82 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require File.dirname(__FILE__) + '/command_helper'
3
+
4
+ describe "github track" do
5
+ include CommandHelper
6
+
7
+ specify "track defunkt should track a new remote for defunkt" do
8
+ running :track, "defunkt" do
9
+ setup_url_for
10
+ @helper.should_receive(:tracking?).with("defunkt").once.and_return(false)
11
+ @command.should_receive(:git).with("remote add defunkt git://github.com/defunkt/project.git").once
12
+ end
13
+ end
14
+
15
+ specify "track --private defunkt should track a new remote for defunkt using ssh" do
16
+ running :track, "--private", "defunkt" do
17
+ setup_url_for
18
+ @helper.should_receive(:tracking?).with("defunkt").and_return(false)
19
+ @command.should_receive(:git).with("remote add defunkt git@github.com:defunkt/project.git")
20
+ end
21
+ end
22
+
23
+ specify "track --ssh defunkt should be equivalent to track --private defunkt" do
24
+ running :track, "--ssh", "defunkt" do
25
+ setup_url_for
26
+ @helper.should_receive(:tracking?).with("defunkt").and_return(false)
27
+ @command.should_receive(:git).with("remote add defunkt git@github.com:defunkt/project.git")
28
+ end
29
+ end
30
+
31
+ specify "track defunkt should die if the defunkt remote exists" do
32
+ running :track, "defunkt" do
33
+ setup_url_for
34
+ @helper.should_receive(:tracking?).with("defunkt").once.and_return(true)
35
+ @command.should_receive(:die).with("Already tracking defunkt").and_return { raise "Died" }
36
+ self.should raise_error(RuntimeError)
37
+ end
38
+ end
39
+
40
+ specify "track should die with no args" do
41
+ running :track do
42
+ @command.should_receive(:die).with("Specify a user to track").and_return { raise "Died" }
43
+ self.should raise_error(RuntimeError)
44
+ end
45
+ end
46
+
47
+ specify "track should accept user/project syntax" do
48
+ running :track, "defunkt/github-gem.git" do
49
+ setup_url_for
50
+ @helper.should_receive(:tracking?).with("defunkt").and_return false
51
+ @command.should_receive(:git).with("remote add defunkt git://github.com/defunkt/github-gem.git")
52
+ end
53
+ end
54
+
55
+ specify "track defunkt/github-gem.git should function with no origin remote" do
56
+ running :track, "defunkt/github-gem.git" do
57
+ @helper.stub!(:url_for).with("origin").and_return ""
58
+ @helper.stub!(:tracking?).and_return false
59
+ @command.should_receive(:git).with("remote add defunkt git://github.com/defunkt/github-gem.git")
60
+ self.should_not raise_error(SystemExit)
61
+ stderr.should_not =~ /^Error/
62
+ end
63
+ end
64
+
65
+ specify "track origin defunkt/github-gem should track defunkt/github-gem as the origin remote" do
66
+ running :track, "origin", "defunkt/github-gem" do
67
+ @helper.stub!(:url_for).with("origin").and_return ""
68
+ @helper.stub!(:tracking?).and_return false
69
+ @command.should_receive(:git).with("remote add origin git://github.com/defunkt/github-gem.git")
70
+ stderr.should_not =~ /^Error/
71
+ end
72
+ end
73
+
74
+ specify "track --private origin defunkt/github-gem should track defunkt/github-gem as the origin remote using ssh" do
75
+ running :track, "--private", "origin", "defunkt/github-gem" do
76
+ @helper.stub!(:url_for).with("origin").and_return ""
77
+ @helper.stub!(:tracking?).and_return false
78
+ @command.should_receive(:git).with("remote add origin git@github.com:defunkt/github-gem.git")
79
+ stderr.should_not =~ /^Error/
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,49 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require File.dirname(__FILE__) + '/commands/command_helper'
3
+
4
+ describe "github" do
5
+ include CommandHelper
6
+
7
+ # -- fallthrough to git if unknown command --
8
+ specify "should fall through to actual git commands" do
9
+ running :commit do
10
+ @command.should_receive(:git_exec).with(["commit", []])
11
+ end
12
+ end
13
+
14
+ specify "should pass along arguments when falling through" do
15
+ running :commit, '-a', '-m', 'yo mama' do
16
+ @command.should_receive(:git_exec).with(["commit", ["-a", "-m", 'yo mama']])
17
+ end
18
+ end
19
+
20
+ # -- default --
21
+ specify "should print the default message" do
22
+ running :default do
23
+ GitHub.should_receive(:descriptions).any_number_of_times.and_return({
24
+ "home" => "Open the home page",
25
+ "browsing" => "Browse the github page for this branch",
26
+ "commands" => "description",
27
+ "tracking" => "Track a new repo"
28
+ })
29
+ GitHub.should_receive(:flag_descriptions).any_number_of_times.and_return({
30
+ "home" => {:flag => "Flag description"},
31
+ "browsing" => {},
32
+ "commands" => {},
33
+ "tracking" => {:flag1 => "Flag one", :flag2 => "Flag two"}
34
+ })
35
+ @command.should_receive(:puts).with(<<-EOS.gsub(/^ /, ''))
36
+ Usage: github command <space separated arguments>
37
+ Available commands:
38
+ browsing => Browse the github page for this branch
39
+ commands => description
40
+ home => Open the home page
41
+ --flag: Flag description
42
+ tracking => Track a new repo
43
+ --flag1: Flag one
44
+ --flag2: Flag two
45
+ EOS
46
+ end
47
+ end
48
+
49
+ end