github-hooker 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1,4 +1,3 @@
1
1
  *.gem
2
2
  .bundle
3
- Gemfile.lock
4
3
  pkg/*
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile CHANGED
@@ -2,3 +2,10 @@ source "http://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in github-hooker.gemspec
4
4
  gemspec
5
+
6
+ gem 'rake'
7
+ gem 'rspec'
8
+ gem 'webmock'
9
+ gem 'guard'
10
+ gem 'guard-bundler'
11
+ gem 'guard-rspec'
data/Gemfile.lock ADDED
@@ -0,0 +1,54 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ github-hooker (0.1.0)
5
+ active_support (~> 3.0.0)
6
+ rest-client (~> 1.6.7)
7
+ thor (~> 0.14.6)
8
+
9
+ GEM
10
+ remote: http://rubygems.org/
11
+ specs:
12
+ active_support (3.0.0)
13
+ activesupport (= 3.0.0)
14
+ activesupport (3.0.0)
15
+ addressable (2.2.6)
16
+ crack (0.3.1)
17
+ diff-lcs (1.1.3)
18
+ ffi (1.0.11)
19
+ guard (1.0.0)
20
+ ffi (>= 0.5.0)
21
+ thor (~> 0.14.6)
22
+ guard-bundler (0.1.3)
23
+ bundler (>= 1.0.0)
24
+ guard (>= 0.2.2)
25
+ guard-rspec (0.6.0)
26
+ guard (>= 0.10.0)
27
+ mime-types (1.17.2)
28
+ rake (0.9.2.2)
29
+ rest-client (1.6.7)
30
+ mime-types (>= 1.16)
31
+ rspec (2.8.0)
32
+ rspec-core (~> 2.8.0)
33
+ rspec-expectations (~> 2.8.0)
34
+ rspec-mocks (~> 2.8.0)
35
+ rspec-core (2.8.0)
36
+ rspec-expectations (2.8.0)
37
+ diff-lcs (~> 1.1.2)
38
+ rspec-mocks (2.8.0)
39
+ thor (0.14.6)
40
+ webmock (1.7.10)
41
+ addressable (~> 2.2, > 2.2.5)
42
+ crack (>= 0.1.7)
43
+
44
+ PLATFORMS
45
+ ruby
46
+
47
+ DEPENDENCIES
48
+ github-hooker!
49
+ guard
50
+ guard-bundler
51
+ guard-rspec
52
+ rake
53
+ rspec
54
+ webmock
data/Guardfile ADDED
@@ -0,0 +1,15 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ group :backend do
5
+ guard :bundler do
6
+ watch('Gemfile')
7
+ end
8
+
9
+ guard :rspec, :cli => '--color --format doc' do
10
+ watch(%r{^spec/.+_spec\.rb$})
11
+ watch(%r{^support/.+\.rb$})
12
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
13
+ watch('spec/spec_helper.rb') { "spec" }
14
+ end
15
+ end
data/bin/github-hooker ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.expand_path("../../lib", __FILE__)
4
+ require "thor"
5
+ require 'github-hooker'
6
+ require 'github-hooker/cli'
7
+
8
+ Github::Hooker::CLI.start
9
+
10
+ # :vim:ft=ruby
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
18
18
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
19
  s.require_paths = ["lib"]
20
20
 
21
- # specify any dependencies here; for example:
22
- # s.add_development_dependency "rspec"
23
- # s.add_runtime_dependency "rest-client"
21
+ s.add_dependency "rest-client", "~> 1.6.7"
22
+ s.add_dependency "thor", "~> 0.14.6"
23
+ s.add_dependency "active_support", "~> 3.0.0"
24
24
  end
data/lib/github-hooker.rb CHANGED
@@ -1,6 +1,44 @@
1
1
  require "github-hooker/version"
2
+ require 'net/http'
3
+ require 'json'
4
+ require 'yaml'
5
+ require 'restclient'
6
+ require 'active_support/core_ext/hash/reverse_merge'
2
7
 
3
8
  module Github
4
9
  module Hooker
10
+ def self.hooks(repo)
11
+ url = "https://api.github.com/repos/#{repo}/hooks"
12
+ github_api(:get, url)
13
+ end
14
+
15
+ def self.add_hook(repo, payload={})
16
+ url = "https://api.github.com/repos/#{repo}/hooks"
17
+ payload = payload.reverse_merge(:active => true)
18
+ github_api(:post, url, :payload => payload.to_json)
19
+ end
20
+
21
+ def self.delete_hook(repo, hook)
22
+ url = "https://api.github.com/repos/#{repo}/hooks/#{hook}"
23
+ github_api(:delete, url)
24
+ end
25
+
26
+ def self.config
27
+ @config ||= YAML.load_file(File.expand_path(config_filename))
28
+ end
29
+
30
+ def self.github_api(method, url, options={})
31
+ options.reverse_merge!(
32
+ :method => method,
33
+ :url => url,
34
+ :user => config["user"],
35
+ :password => config["password"]
36
+ )
37
+ JSON.parse(RestClient::Request.execute(options))
38
+ end
39
+
40
+ def self.config_filename
41
+ "~/.github-hooker.yml"
42
+ end
5
43
  end
6
44
  end
@@ -0,0 +1,73 @@
1
+ module Github
2
+ module Hooker
3
+ class CLI < Thor
4
+ desc "list user/repo", "List hooks in the given repository"
5
+ def list(repo)
6
+ handle_404 do
7
+ check_config!
8
+ hooks = Github::Hooker.hooks(repo)
9
+ hooks.each do |hook|
10
+ puts "#{hook['url']}"
11
+ puts "> name: #{hook['name']}"
12
+ puts "> events: #{hook['events'].join(", ")}"
13
+ puts "> config: #{hook['config']}"
14
+ puts
15
+ end unless hooks.nil?
16
+ end
17
+ end
18
+
19
+ desc "campfire user/repo events", "Add a campfire hook in the given repository. Events must be separated by commas."
20
+ method_option :room, :required => true
21
+ method_option :subdomain, :required => true
22
+ def campfire(repo, events)
23
+ handle_404 do
24
+ check_config!
25
+ events = split_events(events)
26
+ Github::Hooker.add_hook(repo, :name => "campfire", :events => events, :config => options)
27
+ end
28
+ end
29
+
30
+ desc "web user/repo events", "Add a web hook in the given repository. Events must be separated by commas."
31
+ method_option :url, :required => true
32
+ def web(repo, events)
33
+ handle_404 do
34
+ check_config!
35
+ events = split_events(events)
36
+ Github::Hooker.add_hook(repo, :name => "web", :events => events, :config => options)
37
+ end
38
+ end
39
+
40
+ desc "delete user/repo hook", "Delete the hook 1111 from the given repository"
41
+ def delete(repo, hook)
42
+ handle_404 do
43
+ check_config!
44
+ Github::Hooker.delete_hook(repo, hook)
45
+ end
46
+ end
47
+
48
+ private
49
+ def handle_404
50
+ yield
51
+ rescue RestClient::ResourceNotFound
52
+ resource_not_found_message!
53
+ end
54
+
55
+ def split_events(events)
56
+ events.split(",").map(&:strip)
57
+ end
58
+
59
+ def check_config!
60
+ error("~/.github-hooker.yml is not present. Please set 'user', 'password' and 'campfire_token'.") unless File.exist?(File.expand_path(Github::Hooker.config_filename))
61
+ end
62
+
63
+ def resource_not_found_message!
64
+ error("Resource Not Found (404): This repository may not exist or you may not have access to it.")
65
+ end
66
+
67
+ def error(message)
68
+ puts message
69
+ exit 1
70
+ end
71
+ end
72
+ end
73
+ end
@@ -1,5 +1,5 @@
1
1
  module Github
2
2
  module Hooker
3
- VERSION = "0.0.1"
3
+ VERSION = "0.1.0"
4
4
  end
5
5
  end
@@ -0,0 +1,47 @@
1
+ [
2
+ {
3
+ "updated_at": "2012-01-26T16:11:55Z",
4
+ "last_response": {
5
+ "message": "",
6
+ "code": 200
7
+ },
8
+ "created_at": "2012-01-26T13:29:53Z",
9
+ "events": [
10
+ "push",
11
+ "issues",
12
+ "issue_comment",
13
+ "commit_comment",
14
+ "pull_request"
15
+ ],
16
+ "name": "campfire",
17
+ "config": {
18
+ "long_url": "1",
19
+ "token": "aaaaaaaaaaaaaaaaa",
20
+ "subdomain": "company",
21
+ "room": "room"
22
+ },
23
+ "id": 157257,
24
+ "url": "https://api.github.com/repos/user/repo/hooks/157257",
25
+ "active": true
26
+ },
27
+ {
28
+ "updated_at": "2012-01-26T13:56:25Z",
29
+ "last_response": {
30
+ "message": null,
31
+ "code": null
32
+ },
33
+ "created_at": "2012-01-26T13:55:42Z",
34
+ "events": [
35
+ "issue_comment"
36
+ ],
37
+ "name": "web",
38
+ "config": {
39
+ "content_type": "form",
40
+ "url": "http://mycallback.com/callback",
41
+ "secret": null
42
+ },
43
+ "id": 157271,
44
+ "url": "https://api.github.com/repos/user/repo/hooks/157271",
45
+ "active": true
46
+ }
47
+ ]
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+ require 'fileutils'
3
+ require 'thor'
4
+ require 'github-hooker'
5
+ require 'github-hooker/cli'
6
+
7
+ describe "github-hooker" do
8
+ subject { Github::Hooker::CLI.new }
9
+
10
+ before do
11
+ Github::Hooker.stub(:config_filename).and_return("/tmp/.github-hooker.yml")
12
+ FileUtils.touch(Github::Hooker.config_filename)
13
+ stub_config!
14
+ end
15
+
16
+ describe "list" do
17
+ it "calls Github::Hooker with the correct arguments" do
18
+ hooks = [
19
+ {
20
+ "url" => "http://github/hooks/123",
21
+ "name" => "web",
22
+ "events" => ["event1", "event2"],
23
+ "config" => {
24
+ "url" => "http://example.com/callback"
25
+ }
26
+ }
27
+ ]
28
+ Github::Hooker.stub(:hooks).with("user/repo").and_return(hooks)
29
+ subject.list("user/repo")
30
+ end
31
+
32
+ it "handles 404 errors in github API" do
33
+ WebMock.stub_request(:get, "https://user:password@api.github.com/repos/user/non-existent-repo/hooks").
34
+ to_return(:status => 404, :body => "NotFound", :headers => {})
35
+
36
+ $stdout.should_receive(:puts).with("Resource Not Found (404): This repository may not exist or you may not have access to it.")
37
+ expect { subject.list("user/non-existent-repo") }.to raise_error(SystemExit)
38
+ end
39
+ end
40
+
41
+ describe "campfire" do
42
+ it "calls Github::Hooker with the correct arguments" do
43
+ Github::Hooker.stub(:add_hook).with("user/repo", {:name => "campfire", :events => ["pull_requests", "issue"], :config => {}})
44
+ subject.campfire("user/repo", "pull_requests, issue")
45
+ end
46
+ end
47
+
48
+ describe "web" do
49
+ it "calls Github::Hooker with the correct arguments" do
50
+ Github::Hooker.stub(:add_hook).with("user/repo", {:name => "web", :events => ["pull_requests", "issue"], :config => {}})
51
+ subject.web("user/repo", "pull_requests, issue")
52
+ end
53
+ end
54
+
55
+ describe "delete" do
56
+ it "calls Github::Hooker with the correct arguments" do
57
+ Github::Hooker.stub(:delete_hook).with("user/repo", 1010)
58
+ subject.delete("user/repo", 1010)
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+ require 'github-hooker'
3
+
4
+ describe Github::Hooker do
5
+ context "given a valid credential" do
6
+ before do
7
+ stub_config!
8
+ end
9
+
10
+ it "lists the hooks in the given repo" do
11
+ WebMock.stub_request(:get, "https://user:password@api.github.com/repos/user/repo/hooks").
12
+ to_return(:status => 200, :body => fixture_file("list_hooks.json"), :headers => {})
13
+
14
+ list = subject.hooks("user/repo")
15
+
16
+ list[0]["url"].should == "https://api.github.com/repos/user/repo/hooks/157257"
17
+ list[1]["url"].should == "https://api.github.com/repos/user/repo/hooks/157271"
18
+ end
19
+
20
+ it "adds a new campfire hook in the given repo" do
21
+ WebMock.stub_request(:post, "https://user:password@api.github.com/repos/user/repo/hooks").
22
+ with(:body => "{\"active\":\"true\",\"name\":\"campfire\",\"events\":[\"pull_request\",\"issue_comment\"],\"config\":{\"subdomain\":\"company\",\"room\":\"my room\",\"token\":\"abcde\",\"long_url\":\"true\"}}").
23
+ to_return(:status => 200, :body => "{}", :headers => {})
24
+
25
+ hook_options = {
26
+ :name => "campfire",
27
+ :events => ["pull_request", "issue_comment"],
28
+ :active => "true",
29
+ :config => {
30
+ :subdomain => "company",
31
+ :room => "my room",
32
+ :token => "abcde",
33
+ :long_url => "true"
34
+ }
35
+ }
36
+ subject.add_hook("user/repo", hook_options)
37
+ end
38
+
39
+ it "adds a new web hook in the given repo" do
40
+ WebMock.stub_request(:post, "https://user:password@api.github.com/repos/user/repo/hooks").
41
+ with(:body => "{\"active\":\"true\",\"name\":\"web\",\"events\":[\"pull_request\",\"issue\"],\"config\":{\"url\":\"http://example.com/callback\"}}").
42
+ to_return(:status => 200, :body => "{}", :headers => {})
43
+
44
+ hook_options = {
45
+ :name => "web",
46
+ :events => ["pull_request", "issue"],
47
+ :active => "true",
48
+ :config => {
49
+ :url => "http://example.com/callback"
50
+ }
51
+ }
52
+ subject.add_hook("user/repo", hook_options)
53
+ end
54
+
55
+ it "deletes a hook in the given repo" do
56
+ WebMock.stub_request(:delete, "https://user:password@api.github.com/repos/user/repo/hooks/1010").
57
+ to_return(:status => 200, :body => "{}", :headers => {})
58
+
59
+ subject.delete_hook("user/repo", 1010)
60
+ end
61
+ end
62
+ end
63
+
64
+ def fixture_file(name)
65
+ File.read(File.expand_path("../../spec/fixtures/#{name}", __FILE__))
66
+ end
@@ -0,0 +1,10 @@
1
+ require 'webmock/rspec'
2
+
3
+ Dir[File.expand_path("../support/**/*.rb", __FILE__)].each { |f| require f }
4
+
5
+ RSpec.configure do |config|
6
+ config.treat_symbols_as_metadata_keys_with_true_values = true
7
+ config.run_all_when_everything_filtered = true
8
+ config.filter_run :focus
9
+ config.mock_framework = :rspec
10
+ end
@@ -0,0 +1,3 @@
1
+ def stub_config!
2
+ Github::Hooker.stub(:config).and_return({ "user" => "user", "password" => "password", "campfire_token" => "token" })
3
+ end
metadata CHANGED
@@ -1,71 +1,106 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: github-hooker
3
- version: !ruby/object:Gem::Version
4
- hash: 29
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 0
9
- - 1
10
- version: 0.0.1
11
6
  platform: ruby
12
- authors:
13
- - "George Guimara\xCC\x83es"
7
+ authors:
8
+ - George Guimarães
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2012-01-30 00:00:00 Z
19
- dependencies: []
20
-
21
- description: " hook them all "
22
- email:
12
+ date: 2012-02-06 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rest-client
16
+ requirement: &70239803941600 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 1.6.7
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70239803941600
25
+ - !ruby/object:Gem::Dependency
26
+ name: thor
27
+ requirement: &70239803941060 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 0.14.6
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70239803941060
36
+ - !ruby/object:Gem::Dependency
37
+ name: active_support
38
+ requirement: &70239803932200 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 3.0.0
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70239803932200
47
+ description: ! ' hook them all '
48
+ email:
23
49
  - george@plataformatec.com.br
24
- executables: []
25
-
50
+ executables:
51
+ - github-hooker
26
52
  extensions: []
27
-
28
53
  extra_rdoc_files: []
29
-
30
- files:
54
+ files:
31
55
  - .gitignore
56
+ - .rspec
32
57
  - Gemfile
58
+ - Gemfile.lock
59
+ - Guardfile
33
60
  - Rakefile
61
+ - bin/github-hooker
34
62
  - github-hooker.gemspec
35
63
  - lib/github-hooker.rb
64
+ - lib/github-hooker/cli.rb
36
65
  - lib/github-hooker/version.rb
37
- homepage: ""
66
+ - spec/fixtures/list_hooks.json
67
+ - spec/github-hooker/cli_spec.rb
68
+ - spec/github-hooker_spec.rb
69
+ - spec/spec_helper.rb
70
+ - spec/support/config_stub.rb
71
+ homepage: ''
38
72
  licenses: []
39
-
40
73
  post_install_message:
41
74
  rdoc_options: []
42
-
43
- require_paths:
75
+ require_paths:
44
76
  - lib
45
- required_ruby_version: !ruby/object:Gem::Requirement
77
+ required_ruby_version: !ruby/object:Gem::Requirement
46
78
  none: false
47
- requirements:
48
- - - ">="
49
- - !ruby/object:Gem::Version
50
- hash: 3
51
- segments:
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ segments:
52
84
  - 0
53
- version: "0"
54
- required_rubygems_version: !ruby/object:Gem::Requirement
85
+ hash: 61845188583111008
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
87
  none: false
56
- requirements:
57
- - - ">="
58
- - !ruby/object:Gem::Version
59
- hash: 3
60
- segments:
88
+ requirements:
89
+ - - ! '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ segments:
61
93
  - 0
62
- version: "0"
94
+ hash: 61845188583111008
63
95
  requirements: []
64
-
65
96
  rubyforge_project: github-hooker
66
- rubygems_version: 1.8.10
97
+ rubygems_version: 1.8.11
67
98
  signing_key:
68
99
  specification_version: 3
69
100
  summary: hook them all
70
- test_files: []
71
-
101
+ test_files:
102
+ - spec/fixtures/list_hooks.json
103
+ - spec/github-hooker/cli_spec.rb
104
+ - spec/github-hooker_spec.rb
105
+ - spec/spec_helper.rb
106
+ - spec/support/config_stub.rb