magnum-payload 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +24 -0
- data/.rspec +2 -0
- data/Gemfile +6 -0
- data/LICENSE +18 -0
- data/README.md +107 -0
- data/Rakefile +10 -0
- data/lib/magnum/payload/base.rb +62 -0
- data/lib/magnum/payload/beanstalk.rb +43 -0
- data/lib/magnum/payload/bitbucket.rb +53 -0
- data/lib/magnum/payload/custom.rb +19 -0
- data/lib/magnum/payload/github.rb +50 -0
- data/lib/magnum/payload/gitlab.rb +38 -0
- data/lib/magnum/payload/gitslice.rb +21 -0
- data/lib/magnum/payload/message_parser.rb +11 -0
- data/lib/magnum/payload/version.rb +5 -0
- data/lib/magnum/payload.rb +24 -0
- data/magnum-payload.gemspec +23 -0
- data/spec/fixtures/beanstalk/git.json +28 -0
- data/spec/fixtures/beanstalk/hg.json +27 -0
- data/spec/fixtures/beanstalk/svn.json +15 -0
- data/spec/fixtures/bitbucket/git.json +48 -0
- data/spec/fixtures/bitbucket/hg.json +48 -0
- data/spec/fixtures/github/deleted.json +39 -0
- data/spec/fixtures/github/forced.json +58 -0
- data/spec/fixtures/github/new_branch.json +77 -0
- data/spec/fixtures/github/new_tag.json +58 -0
- data/spec/fixtures/github.json +113 -0
- data/spec/fixtures/gitlab/commits.json +34 -0
- data/spec/fixtures/gitlab/create_branch.json +15 -0
- data/spec/fixtures/gitlab/delete_branch.json +15 -0
- data/spec/fixtures/gitslice.json +9 -0
- data/spec/payload/base_spec.rb +52 -0
- data/spec/payload/beanstalk_spec.rb +114 -0
- data/spec/payload/bitbucket_spec.rb +94 -0
- data/spec/payload/github_spec.rb +74 -0
- data/spec/payload/gitlab_spec.rb +53 -0
- data/spec/payload/gitslice_spec.rb +33 -0
- data/spec/payload/message_parser_spec.rb +45 -0
- data/spec/payload_spec.rb +35 -0
- data/spec/spec_helper.rb +17 -0
- metadata +177 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NWM5YzVmNTc0ZTJhZTIwNDA4OGExODViN2E2NDdkOWViMjI4MWQxNw==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
NWQzZjM0NmZiYWNiMzhhYzgwM2MxZWVhY2RkNzdmMjVjODMyOTIyYQ==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
MDM2MWEyNzhiNjkxYTI3OTZiMDI3M2VmYjBjYTgwYWQzOGRjNmFjNmE2Zjg4
|
10
|
+
MWFmOTFjZThjNTBlOWEwYmI2NzgxMTUzY2I4N2I5Y2NjYmY4M2I0MDg5NmNj
|
11
|
+
NDE0NTliNjlmMzEzOWRiYTBmZmRlM2MyNTNjZDBkYjFhNmU4MDk=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
OGVmMGM2ZTU5MjFmNmFmZDQwOWVkOTE3M2UzZTMxYTNmYTI1N2E1ZWQzNTVk
|
14
|
+
NTc3MWFmNWUyZGIxOTAzMTZhZmIyNjE1ODgxYjQ1NGFlYmM1MWFkZmIyNGNj
|
15
|
+
MTA2Y2YzYjJjNWM5ODRlYTAwMjAwMzA5MzFiMzIwODEyZTc1OWY=
|
data/.gitignore
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
*.swp
|
4
|
+
*.tmproj
|
5
|
+
*~
|
6
|
+
.DS_Store
|
7
|
+
.\#*
|
8
|
+
.bundle
|
9
|
+
.config
|
10
|
+
.yardoc
|
11
|
+
Gemfile.lock
|
12
|
+
InstalledFiles
|
13
|
+
\#*
|
14
|
+
_yardoc
|
15
|
+
coverage
|
16
|
+
doc/
|
17
|
+
lib/bundler/man
|
18
|
+
pkg
|
19
|
+
rdoc
|
20
|
+
spec/reports
|
21
|
+
test/tmp
|
22
|
+
test/version_tmp
|
23
|
+
tmp
|
24
|
+
tmtags
|
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
Copyright (c) 2013 Magnum CI, Dan Sosedoff <dan.sosedoff@gmail.com>
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
4
|
+
this software and associated documentation files (the "Software"), to deal in
|
5
|
+
the Software without restriction, including without limitation the rights to
|
6
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
7
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
8
|
+
subject to the following conditions
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
15
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
16
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
17
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
18
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
|
data/README.md
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
# magnum-payload
|
2
|
+
|
3
|
+
Ruby library to parse and process JSON-formatted payloads from code hosting providers.
|
4
|
+
It accepts any commits payloads and transforms them into identical data structures.
|
5
|
+
|
6
|
+
If you need to integrate web-hooks from Github, Bitbucket or Gitlab this is definitely
|
7
|
+
worth checking out. Check examples for details.
|
8
|
+
|
9
|
+
## Supported platforms
|
10
|
+
|
11
|
+
You can integrate with the following providers:
|
12
|
+
|
13
|
+
- [Github](https://github.com) - git
|
14
|
+
- [Bitbucket](https://bitbucket.org) - git, mercurial
|
15
|
+
- [Gitlab](http://gitlab.org/) - git
|
16
|
+
- [Beanstalkapp](http://beanstalkapp.com/) - git, mercurial, subversion
|
17
|
+
- Your own server - git
|
18
|
+
|
19
|
+
## Installation
|
20
|
+
|
21
|
+
Add dependency to Gemfile:
|
22
|
+
|
23
|
+
```
|
24
|
+
gem 'magnum-payload',
|
25
|
+
github: 'magnumci/magnum-payload',
|
26
|
+
require: 'magnum/payload'
|
27
|
+
```
|
28
|
+
|
29
|
+
NOTE: Library is not distributed via Rubygems.
|
30
|
+
|
31
|
+
## Usage
|
32
|
+
|
33
|
+
Example:
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
require 'magnum/payload'
|
37
|
+
|
38
|
+
# Shorthand method to parse payload
|
39
|
+
Magnum::Payload.parse('github', 'JSON data') # => Magnum::Payload::Github
|
40
|
+
Magnum::Payload.parse('bitbucket', 'JSON data') # => Magnum::Payload::Bitbucket
|
41
|
+
Magnum::Payload.parse('gitlab', 'JSON data') # => Magnum::Payload::Bitbucket
|
42
|
+
|
43
|
+
# Or directly initialize a class
|
44
|
+
payload = Magnum::Payload::Github.new('JSON data')
|
45
|
+
|
46
|
+
# Detect skip
|
47
|
+
payload.skip?
|
48
|
+
payload.skip_message?
|
49
|
+
```
|
50
|
+
|
51
|
+
See `Payload Attributes` section for payload instance details.
|
52
|
+
|
53
|
+
## Payload Classes
|
54
|
+
|
55
|
+
All payload classes are inherited from `Magnum::Payload::Base`:
|
56
|
+
|
57
|
+
- Magnum::Payload::Github
|
58
|
+
- Magnum::Payload::Gitlab
|
59
|
+
- Magnum::Payload::Beanstalk
|
60
|
+
- Magnum::Payload::Bitbucket
|
61
|
+
- Magnum::Payload::Custom
|
62
|
+
|
63
|
+
## Payload Attributes
|
64
|
+
|
65
|
+
Attributes are depending on payload class.
|
66
|
+
|
67
|
+
- `raw_data` - Original payload string or hash
|
68
|
+
- `data` - Formatted hash instance
|
69
|
+
- `skip` - Skip flag that indicated full payload skip (deleted head, etc)
|
70
|
+
- `commit` - Code revision (SHA1, number)
|
71
|
+
- `branch` - Code branch name (git, hg, svn)
|
72
|
+
- `author` - Commit author name
|
73
|
+
- `committer` - Commit committer name (git)
|
74
|
+
- `message` - Commit message text
|
75
|
+
- `committer_email` - Committer email (git)
|
76
|
+
- `author_email` - Author email (git)
|
77
|
+
- `commit_url` - Direct URL to view commit diff
|
78
|
+
- `compare_url` - Direct URL to view commits diff
|
79
|
+
|
80
|
+
## Test Suite
|
81
|
+
|
82
|
+
To execute test suite run:
|
83
|
+
|
84
|
+
```
|
85
|
+
rake test
|
86
|
+
```
|
87
|
+
|
88
|
+
## License
|
89
|
+
|
90
|
+
Copyright (c) 2013 Magnum CI, Dan Sosedoff <dan.sosedoff@gmail.com>
|
91
|
+
|
92
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
93
|
+
this software and associated documentation files (the "Software"), to deal in
|
94
|
+
the Software without restriction, including without limitation the rights to
|
95
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
96
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
97
|
+
subject to the following conditions
|
98
|
+
|
99
|
+
The above copyright notice and this permission notice shall be included in all
|
100
|
+
copies or substantial portions of the Software
|
101
|
+
|
102
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
103
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
104
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
105
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
106
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
107
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
|
data/Rakefile
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'hashr'
|
3
|
+
|
4
|
+
module Magnum
|
5
|
+
module Payload
|
6
|
+
class Base
|
7
|
+
include Magnum::Payload::MessageParser
|
8
|
+
|
9
|
+
attr_reader :raw_data, :data
|
10
|
+
attr_reader :skip, :test
|
11
|
+
|
12
|
+
attr_reader :commit, :branch, :author, :committer, :message
|
13
|
+
attr_reader :committer_email, :author_email
|
14
|
+
attr_reader :commit_url, :compare_url
|
15
|
+
|
16
|
+
def initialize(payload)
|
17
|
+
@skip = false # Do not skip by default
|
18
|
+
@test = false # Do not treat as test payload
|
19
|
+
@raw_data = payload
|
20
|
+
@data = parse_payload(payload)
|
21
|
+
|
22
|
+
parse!
|
23
|
+
|
24
|
+
@skip = skip_message? unless @skip
|
25
|
+
end
|
26
|
+
|
27
|
+
def attributes_hash
|
28
|
+
{
|
29
|
+
'commit' => commit,
|
30
|
+
'branch' => branch,
|
31
|
+
'author' => author,
|
32
|
+
'committer' => committer,
|
33
|
+
'message' => message,
|
34
|
+
'commit_url' => commit_url,
|
35
|
+
'compare_url' => compare_url
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def parse!
|
40
|
+
raise "Not implemented in base class"
|
41
|
+
end
|
42
|
+
|
43
|
+
def skip?
|
44
|
+
skip == true
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def parse_payload(payload)
|
50
|
+
if payload.kind_of?(String)
|
51
|
+
Hashr.new(JSON.parse(payload))
|
52
|
+
elsif payload.kind_of?(Hash)
|
53
|
+
Hashr.new(payload)
|
54
|
+
else
|
55
|
+
raise ArgumentError, "String or Hash required"
|
56
|
+
end
|
57
|
+
rescue JSON::ParserError
|
58
|
+
raise Magnum::Payload::ParseError, "Valid JSON required"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Magnum
|
2
|
+
class Payload::Beanstalk < Payload::Base
|
3
|
+
def parse!
|
4
|
+
data.revision ? parse_svn! : parse_git!
|
5
|
+
detect_fake_payload!
|
6
|
+
end
|
7
|
+
|
8
|
+
def last_commit
|
9
|
+
@last_commit ||= Hashr.new(data.commits.last)
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def parse_git!
|
15
|
+
@commit = last_commit.id
|
16
|
+
@branch = data.branch
|
17
|
+
@message = last_commit.message
|
18
|
+
@author = last_commit.author.name
|
19
|
+
@author_email = last_commit.author.email
|
20
|
+
@commit_url = last_commit.url
|
21
|
+
end
|
22
|
+
|
23
|
+
def parse_svn!
|
24
|
+
@commit = data.revision
|
25
|
+
@branch = 'master'
|
26
|
+
@author = data.author_full_name || data.author
|
27
|
+
@author_email = data.author_email
|
28
|
+
@committer = @author
|
29
|
+
@committer_email = @author_email
|
30
|
+
@commit_url = data.changeset_url
|
31
|
+
@message = data.message
|
32
|
+
end
|
33
|
+
|
34
|
+
def detect_fake_payload!
|
35
|
+
if data.before && data.after
|
36
|
+
if data.before =~ /^[0]+$/ && data.after =~ /^[1]+$/
|
37
|
+
@skip = true
|
38
|
+
@test = true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Magnum
|
2
|
+
class Payload::Bitbucket < Payload::Base
|
3
|
+
def parse!
|
4
|
+
commit = Hashr.new(data.commits.last)
|
5
|
+
|
6
|
+
branch = commit.branch || commit.branches.first || 'none'
|
7
|
+
revision = commit.revision || commit.raw_node
|
8
|
+
author = parse_author(commit.raw_author)
|
9
|
+
|
10
|
+
@commit = revision
|
11
|
+
@author = author.name
|
12
|
+
@author_email = author.email
|
13
|
+
@message = commit.message.strip
|
14
|
+
@branch = branch
|
15
|
+
@commit_url = make_url("commits/#{revision}")
|
16
|
+
|
17
|
+
if data.commits.size > 1
|
18
|
+
parse_compare_url(revision)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def make_url(path=nil)
|
23
|
+
[site_url, repo_url, path].compact.join
|
24
|
+
end
|
25
|
+
|
26
|
+
def site_url
|
27
|
+
data.canon_url
|
28
|
+
end
|
29
|
+
|
30
|
+
def repo_url
|
31
|
+
data.repository.absolute_url
|
32
|
+
end
|
33
|
+
|
34
|
+
def parse_author(str)
|
35
|
+
case str
|
36
|
+
when /<.+>/
|
37
|
+
m, name, email = *str.match(/(.*) <(.+?)>/)
|
38
|
+
Hashr.new(:name => name, :email => email)
|
39
|
+
else
|
40
|
+
Hashr.new(:name => str)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def parse_compare_url(revision)
|
47
|
+
first_commit = Hashr.new(data.commits.first)
|
48
|
+
rev_start = first_commit.revision || first_commit.raw_node
|
49
|
+
rev_end = revision
|
50
|
+
@compare_url = make_url("compare/#{rev_start}..#{rev_end}")
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Magnum
|
2
|
+
class Payload::Custom < Payload::Base
|
3
|
+
def parse!
|
4
|
+
assign_payload
|
5
|
+
end
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def assign_payload
|
10
|
+
@commit = data.commit
|
11
|
+
@author = data.author
|
12
|
+
@committer = data.committer
|
13
|
+
@message = data.message
|
14
|
+
@branch = data.branch
|
15
|
+
@commit_url = data.commit_url
|
16
|
+
@compare_url = data.compare_url
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Magnum
|
2
|
+
class Payload::Github < Payload::Base
|
3
|
+
def parse!
|
4
|
+
assign_payload unless skip_payload?
|
5
|
+
end
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def assign_payload
|
10
|
+
@commit = last_commit.id
|
11
|
+
@author = last_commit.author.name
|
12
|
+
@author_email = last_commit.author.email
|
13
|
+
@committer = last_commit.committer.name
|
14
|
+
@committer_email = last_commit.committer.email
|
15
|
+
@message = last_commit.message
|
16
|
+
@branch = data.ref.split('/').last
|
17
|
+
@commit_url = last_commit.url
|
18
|
+
@compare_url = data.compare
|
19
|
+
end
|
20
|
+
|
21
|
+
def skip_payload?
|
22
|
+
@skip = true if deleted? || last_commit.nil?
|
23
|
+
@skip = true if data.ref =~ /tags/
|
24
|
+
|
25
|
+
@skip
|
26
|
+
end
|
27
|
+
|
28
|
+
# Check if push is forced
|
29
|
+
# @return [Boolean]
|
30
|
+
def forced?
|
31
|
+
data.forced == true
|
32
|
+
end
|
33
|
+
|
34
|
+
# Check if head is deleted
|
35
|
+
# @return [Boolean]
|
36
|
+
def deleted?
|
37
|
+
data.deleted == true
|
38
|
+
end
|
39
|
+
|
40
|
+
# Get last commit in the push
|
41
|
+
# @return [Hashr]
|
42
|
+
def last_commit
|
43
|
+
if forced?
|
44
|
+
data.head_commit
|
45
|
+
else
|
46
|
+
Hashr.new(data.commits.last)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Magnum
|
2
|
+
class Payload::Gitlab < Payload::Base
|
3
|
+
ZERO_SHA = /\A[0]{40}\z/
|
4
|
+
|
5
|
+
def parse!
|
6
|
+
assign_payload unless skip_payload?
|
7
|
+
end
|
8
|
+
|
9
|
+
def last_commit
|
10
|
+
@last_commit ||= Hashr.new(data.commits.last)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def assign_payload
|
16
|
+
@commit = data.after
|
17
|
+
@branch = data.ref.split('/').last
|
18
|
+
|
19
|
+
if data.commits.any?
|
20
|
+
@author = last_commit.author.name
|
21
|
+
@author_email = last_commit.author.email
|
22
|
+
@committer = @author
|
23
|
+
@committer_email = @author_email
|
24
|
+
@message = last_commit.message
|
25
|
+
@commit_url = last_commit.url
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def skip_payload?
|
30
|
+
@skip = true if deleted?
|
31
|
+
@skip
|
32
|
+
end
|
33
|
+
|
34
|
+
def deleted?
|
35
|
+
data.before !~ ZERO_SHA && data.after =~ ZERO_SHA
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|