codefumes 0.1.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.
- data/History.txt +4 -0
- data/Manifest.txt +24 -0
- data/README.txt +102 -0
- data/Rakefile +31 -0
- data/config/website.yml.sample +2 -0
- data/lib/codefumes.rb +11 -0
- data/lib/codefumes/api.rb +19 -0
- data/lib/codefumes/commit.rb +144 -0
- data/lib/codefumes/config_file.rb +85 -0
- data/lib/codefumes/payload.rb +103 -0
- data/lib/codefumes/project.rb +113 -0
- data/spec/codefumes/api_spec.rb +33 -0
- data/spec/codefumes/commit_spec.rb +270 -0
- data/spec/codefumes/config_file_spec.rb +142 -0
- data/spec/codefumes/payload_spec.rb +161 -0
- data/spec/codefumes/project_spec.rb +274 -0
- data/spec/spec.opts +1 -1
- data/spec/spec_helper.rb +19 -0
- data/tasks/rspec.rake +21 -0
- data/website/index.html +11 -0
- data/website/index.txt +81 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/screen.css +159 -0
- data/website/template.html.erb +50 -0
- metadata +110 -0
data/History.txt
ADDED
data/Manifest.txt
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
History.txt
|
2
|
+
Manifest.txt
|
3
|
+
README.txt
|
4
|
+
Rakefile
|
5
|
+
config/website.yml.sample
|
6
|
+
lib/codefumes.rb
|
7
|
+
lib/codefumes/api.rb
|
8
|
+
lib/codefumes/commit.rb
|
9
|
+
lib/codefumes/config_file.rb
|
10
|
+
lib/codefumes/payload.rb
|
11
|
+
lib/codefumes/project.rb
|
12
|
+
spec/codefumes/api_spec.rb
|
13
|
+
spec/codefumes/commit_spec.rb
|
14
|
+
spec/codefumes/config_file_spec.rb
|
15
|
+
spec/codefumes/payload_spec.rb
|
16
|
+
spec/codefumes/project_spec.rb
|
17
|
+
spec/spec.opts
|
18
|
+
spec/spec_helper.rb
|
19
|
+
tasks/rspec.rake
|
20
|
+
website/index.html
|
21
|
+
website/index.txt
|
22
|
+
website/javascripts/rounded_corners_lite.inc.js
|
23
|
+
website/stylesheets/screen.css
|
24
|
+
website/template.html.erb
|
data/README.txt
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
= codefumes
|
2
|
+
|
3
|
+
http://www.codefumes.com
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
CodeFumes.com[http://codefumes.com] is a service intended to help people
|
8
|
+
involved with software projects who are interested in tracking, sharing,
|
9
|
+
and reviewing metrics/information about a project in relation to the
|
10
|
+
commits of said project's repository. The site supports a small set of
|
11
|
+
'standard' metrics, but also provides a simple method of supplying
|
12
|
+
and retrieving custom metrics, allowing users to gather any metric they
|
13
|
+
are interested in tracking.
|
14
|
+
|
15
|
+
The 'codefumes' gem is an implementation of the
|
16
|
+
CodeFumes.com[http://codefumes.com] API. The intention of the
|
17
|
+
gem is to simplify integration with CodeFumes.com for developers of
|
18
|
+
other libraries & and applications.
|
19
|
+
|
20
|
+
For an example of another library using the current features of this
|
21
|
+
gem, you can refer to the
|
22
|
+
'codefumes_harvester[http://codefumes.rubyforge.org/codefumes_harvester]' gem.
|
23
|
+
|
24
|
+
== FEATURES/PROBLEMS:
|
25
|
+
|
26
|
+
=== Features
|
27
|
+
* Saving, finding, marshalling, and destroying CodeFumes
|
28
|
+
projects
|
29
|
+
* Associating and retrieving a repository's history of commits for a
|
30
|
+
CodeFumes 'project'
|
31
|
+
* Simple interface for accessing both CodeFumes's 'standard' commit
|
32
|
+
metrics, as well as custom commit attributes; simplifying
|
33
|
+
integration with other tools & libraries users may be interested in
|
34
|
+
using.
|
35
|
+
* Interfaces with the CodeFumes config file (used to track projects a
|
36
|
+
user has created on the site)
|
37
|
+
|
38
|
+
=== Problems / Things to Note
|
39
|
+
|
40
|
+
* CodeFumes 'projects' are repository-specific, not branch-specific.
|
41
|
+
|
42
|
+
== SYNOPSIS:
|
43
|
+
|
44
|
+
require 'codefumes'
|
45
|
+
|
46
|
+
# Creating & finding a CodeFumes project
|
47
|
+
p = Project.save # optionally providing a custom public key: :public_key => 'Abc3'
|
48
|
+
found_p = Project.find(p.public_key)
|
49
|
+
p.pulic_key # => 'Abc3'
|
50
|
+
p.api_uri # => 'http://codefumes.com/api/v1/xml/Abc3'
|
51
|
+
|
52
|
+
# Commits
|
53
|
+
c = Commit.find(<commit identifier>)
|
54
|
+
c.identifier # => git commit SHA (svn support coming soon)
|
55
|
+
c.short_message # => commit message
|
56
|
+
|
57
|
+
# Custom attributes associated with a commit
|
58
|
+
c.custom_attributes[:coverage] # => "80"
|
59
|
+
|
60
|
+
|
61
|
+
# Payloads, used to break up large HTTP requests
|
62
|
+
content = Payload.prepare(payload_content)
|
63
|
+
content.each {|chunk| chunk.save}
|
64
|
+
|
65
|
+
== REQUIREMENTS:
|
66
|
+
|
67
|
+
* httparty (0.4.3)
|
68
|
+
|
69
|
+
== INSTALL:
|
70
|
+
|
71
|
+
From RubyForge:
|
72
|
+
|
73
|
+
sudo gem install codefumes
|
74
|
+
|
75
|
+
Or, from Github:
|
76
|
+
|
77
|
+
sudo gem install cosyn-codefumes
|
78
|
+
|
79
|
+
== LICENSE:
|
80
|
+
|
81
|
+
(The MIT License)
|
82
|
+
|
83
|
+
Copyright (c) 2009 Cosyn Technologies, Inc.
|
84
|
+
|
85
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
86
|
+
a copy of this software and associated documentation files (the
|
87
|
+
'Software'), to deal in the Software without restriction, including
|
88
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
89
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
90
|
+
permit persons to whom the Software is furnished to do so, subject to
|
91
|
+
the following conditions:
|
92
|
+
|
93
|
+
The above copyright notice and this permission notice shall be
|
94
|
+
included in all copies or substantial portions of the Software.
|
95
|
+
|
96
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
97
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
98
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
99
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
100
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
101
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
102
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
%w[hoe rake rake/clean fileutils rubigen hoe].each { |f| require f }
|
2
|
+
|
3
|
+
require File.dirname(__FILE__) + '/lib/codefumes'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require "hanna/rdoctask"
|
7
|
+
rescue LoadError
|
8
|
+
require 'rake/rdoctask'
|
9
|
+
end
|
10
|
+
|
11
|
+
# Load in the harvester ane metric_fu gems if available so we can collect metrics
|
12
|
+
begin
|
13
|
+
require "metric_fu"
|
14
|
+
require "codefumes_harvester"
|
15
|
+
rescue LoadError
|
16
|
+
end
|
17
|
+
|
18
|
+
$hoe = Hoe.spec('codefumes') do |p|
|
19
|
+
p.developer('Cosyn Technologies', 'devs@codefumes.com')
|
20
|
+
p.summary = "API gem for the CodeFumes website"
|
21
|
+
p.extra_deps = [
|
22
|
+
['httparty','>= 0.4.3']
|
23
|
+
]
|
24
|
+
p.extra_dev_deps = [
|
25
|
+
['jscruggs-metric_fu', ">= 1.1.5"],
|
26
|
+
]
|
27
|
+
end
|
28
|
+
|
29
|
+
Dir['tasks/**/*.rake'].each { |t| load t}
|
30
|
+
|
31
|
+
task :default => [:spec]
|
data/lib/codefumes.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module CodeFumes
|
2
|
+
class API
|
3
|
+
include HTTParty
|
4
|
+
|
5
|
+
format :xml
|
6
|
+
|
7
|
+
BASE_URIS = {
|
8
|
+
:production => 'http://www.codefumes.com/api/v1/xml',
|
9
|
+
:test => 'http://test.codefumes.com/api/v1/xml'
|
10
|
+
}
|
11
|
+
|
12
|
+
def self.mode(mode)
|
13
|
+
base_uri(BASE_URIS[mode]) if BASE_URIS[mode]
|
14
|
+
end
|
15
|
+
|
16
|
+
mode(:production)
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
module CodeFumes
|
2
|
+
# Similar to a revision control system, a Commit encompasses a set of
|
3
|
+
# changes to a codebase, who made them, when said changes were applied
|
4
|
+
# to the previous revision of codebase, et cetera.
|
5
|
+
#
|
6
|
+
# A Commit has a concept of 'standard attributes' which will always be
|
7
|
+
# present in a response from CodeFumes.com[http://codefumes.com], such
|
8
|
+
# as the +identifier+, +author+, and +commit_message+ (see the list of
|
9
|
+
# attributes for a comprehensive listing). In addition to this, users
|
10
|
+
# are able to associate 'custom attributes' to a Commit, allowing
|
11
|
+
# users to link any number of attributes with a commit identifier and
|
12
|
+
# easily retrieve them later.
|
13
|
+
#
|
14
|
+
# One thing to note about Commit objects is that they are read-only.
|
15
|
+
# To associate metrics with a Commit object, a Payload object should
|
16
|
+
# be created and saved. Refer to the Payload documentation for more
|
17
|
+
# information.
|
18
|
+
class Commit < CodeFumes::API
|
19
|
+
attr_reader :identifier, :author_name, :author_email, :committer_name,
|
20
|
+
:committer_email, :short_message, :message,:committed_at,
|
21
|
+
:authored_at, :uploaded_at, :api_uri, :parent_identifiers,
|
22
|
+
:line_additions, :line_deletions, :line_total,
|
23
|
+
:affected_file_count, :custom_attributes
|
24
|
+
|
25
|
+
# Instantiates a new Commit object
|
26
|
+
#
|
27
|
+
# Accepts a Hash of options, including:
|
28
|
+
# * identifier
|
29
|
+
# * author_email
|
30
|
+
# * author_name
|
31
|
+
# * committer_email
|
32
|
+
# * committer_name
|
33
|
+
# * short_message
|
34
|
+
# * message
|
35
|
+
# * committed_at
|
36
|
+
# * authored_at
|
37
|
+
# * uploaded_at
|
38
|
+
# * api_uri
|
39
|
+
# * parent_identifiers
|
40
|
+
# * line_additions
|
41
|
+
# * line_deletions
|
42
|
+
# * line_total
|
43
|
+
# * affected_file_count
|
44
|
+
# * custom_attributes
|
45
|
+
#
|
46
|
+
# +custom_attributes+ should be a Hash of attribute_name/value
|
47
|
+
# pairs associated with the commit. All other attributes are
|
48
|
+
# expected to be String values, other than +committed_at+ and
|
49
|
+
# +authored_at+, which are expected to be DateTime objects.
|
50
|
+
# Technically speaking, you could pass anything you wanted into
|
51
|
+
# the fields, but when using with the CodeFumes API, the attribute
|
52
|
+
# values will be of the type String, DateTime, or Hash.
|
53
|
+
def initialize(options)
|
54
|
+
@identifier = options["identifier"]
|
55
|
+
@author_email = options["author_email"]
|
56
|
+
@author_name = options["author_name"]
|
57
|
+
@committer_email = options["committer_email"]
|
58
|
+
@committer_name = options["committer_name"]
|
59
|
+
@short_message = options["short_message"]
|
60
|
+
@message = options["message"]
|
61
|
+
@committed_at = options["committed_at"]
|
62
|
+
@authored_at = options["authored_at"]
|
63
|
+
@uploaded_at = options["uploaded_at"]
|
64
|
+
@api_uri = options["api_uri"]
|
65
|
+
@parent_identifiers = options["parent_identifiers"]
|
66
|
+
@line_additions = options["line_additions"]
|
67
|
+
@line_deletions = options["line_deletions"]
|
68
|
+
@line_total = options["line_total"]
|
69
|
+
@affected_file_count = options["affected_file_count"]
|
70
|
+
@custom_attributes = options["custom_attributes"] || {}
|
71
|
+
convert_custom_attributes_keys_to_symbols
|
72
|
+
end
|
73
|
+
|
74
|
+
# Returns the name of the author and the email associated
|
75
|
+
# with the commit in a string formatted as:
|
76
|
+
# "Name [email_address]"
|
77
|
+
# (ie: "John Doe [jdoe@example.com]")
|
78
|
+
def author
|
79
|
+
"#{author_name} [#{author_email}]"
|
80
|
+
end
|
81
|
+
|
82
|
+
# Returns the name of the committer and the email associated
|
83
|
+
# with the commit in a string formatted as:
|
84
|
+
# "Name [email_address]"
|
85
|
+
# (ie: "John Doe [jdoe@example.com]")
|
86
|
+
def committer
|
87
|
+
"#{committer_name} [#{committer_email}]"
|
88
|
+
end
|
89
|
+
|
90
|
+
# Returns the Commit object associated with the supplied identifier.
|
91
|
+
# Returns nil if the identifier is not found.
|
92
|
+
def self.find(identifier)
|
93
|
+
response = get("/commits/#{identifier}")
|
94
|
+
case response.code
|
95
|
+
when 200
|
96
|
+
return nil if response["commit"].empty?
|
97
|
+
new(response["commit"])
|
98
|
+
else
|
99
|
+
nil
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Returns a collection of commits associated with the specified
|
104
|
+
# Project public key.
|
105
|
+
def self.all(project_public_key)
|
106
|
+
response = get("/projects/#{project_public_key}/commits")
|
107
|
+
case response.code
|
108
|
+
when 200
|
109
|
+
return [] if response["commits"].empty? || response["commits"]["commit"].nil?
|
110
|
+
response["commits"]["commit"].map do |commit_data|
|
111
|
+
new(commit_data)
|
112
|
+
end
|
113
|
+
else
|
114
|
+
nil
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# Returns the most recent commit associated with the specified
|
119
|
+
# Project public key.
|
120
|
+
def self.latest(project_public_key)
|
121
|
+
response = get("/projects/#{project_public_key}/commits/latest")
|
122
|
+
case response.code
|
123
|
+
when 200
|
124
|
+
new(response["commit"])
|
125
|
+
else
|
126
|
+
nil
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# Returns the commit identifier of the most recent commit of with
|
131
|
+
# the specified Project public key.
|
132
|
+
def self.latest_identifier(project_public_key)
|
133
|
+
latest_commit = latest(project_public_key)
|
134
|
+
latest_commit.nil? ? nil : latest_commit.identifier
|
135
|
+
end
|
136
|
+
|
137
|
+
private
|
138
|
+
def convert_custom_attributes_keys_to_symbols
|
139
|
+
@custom_attributes = @custom_attributes.inject({}) do |results, key_and_value|
|
140
|
+
results.merge! key_and_value.first.to_sym => key_and_value.last
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module CodeFumes
|
2
|
+
# CodeFumes uses a global (per-user) config file to store relevant
|
3
|
+
# information around a user's use of the service. Doing so addresses
|
4
|
+
# the following goals:
|
5
|
+
# * A defined location for all tools to utilize which contains URI's
|
6
|
+
# and and keys for all projects a user has set up on
|
7
|
+
# CodeFumes.com[http://codefumes.com], simplifying integration.
|
8
|
+
# * Associating (or disassociating) a project to (or from) a CodeFumes
|
9
|
+
# project does not require any modifications to said project's
|
10
|
+
# repository.
|
11
|
+
# * Simplified the implementation of 'user-less' projects on the
|
12
|
+
# website.
|
13
|
+
#
|
14
|
+
# This class wraps up reading and writing this config file so other
|
15
|
+
# developers should not have to concern themselves with how to
|
16
|
+
# serialize & write the data of a project into the appropriate format,
|
17
|
+
# output file, et cetera.
|
18
|
+
class ConfigFile
|
19
|
+
DEFAULT_FILE_STRUCTURE = {}
|
20
|
+
DEFAULT_PATH = File.expand_path('~/.codefumes_config')
|
21
|
+
|
22
|
+
class << self
|
23
|
+
# Returns the path to the CodeFumes global (per-user) config file.
|
24
|
+
# The default path is '~/.codefumes_config'.
|
25
|
+
def path
|
26
|
+
@path || ENV['CODEFUMES_CONFIG_FILE'] || DEFAULT_PATH.dup
|
27
|
+
end
|
28
|
+
|
29
|
+
# Sets the path which should be used for storing the configuration
|
30
|
+
# CodeFumes.com data.
|
31
|
+
def path=(custom_path)
|
32
|
+
@path = custom_path.nil? ? path : File.expand_path(custom_path)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Store the supplied project into the CodeFumes config file.
|
36
|
+
def save_project(project)
|
37
|
+
config = serialized
|
38
|
+
if config[:projects]
|
39
|
+
config[:projects].merge!(project.to_config)
|
40
|
+
else
|
41
|
+
config[:projects] = project.to_config
|
42
|
+
end
|
43
|
+
write(config)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Remove the supplied project from the CodeFumes config file.
|
47
|
+
def delete_project(project)
|
48
|
+
config = serialized
|
49
|
+
config[:projects] && config[:projects].delete(project.public_key.to_sym)
|
50
|
+
write(config)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Returns a Hash representation of the CodeFumes config file
|
54
|
+
def serialized
|
55
|
+
empty? ? DEFAULT_FILE_STRUCTURE.dup : loaded
|
56
|
+
end
|
57
|
+
|
58
|
+
# Returns a Hash representation of a specific project contained in
|
59
|
+
# the CodeFumes config file.
|
60
|
+
def options_for_project(public_key)
|
61
|
+
config = serialized
|
62
|
+
public_key && config[:projects] && config[:projects][public_key.to_sym] || {}
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
def write(serializable_object)
|
67
|
+
File.open(path, 'w') do |f|
|
68
|
+
f.puts YAML::dump(serializable_object)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def exists?
|
73
|
+
File.exists?(path)
|
74
|
+
end
|
75
|
+
|
76
|
+
def empty?
|
77
|
+
!(exists? && loaded)
|
78
|
+
end
|
79
|
+
|
80
|
+
def loaded
|
81
|
+
YAML::load_file(path)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
module CodeFumes
|
2
|
+
# Payloads are intended to simplify sending up large amounts of
|
3
|
+
# content at one time. For example, when sending up the entire
|
4
|
+
# history of a repository, making a POST request for each commit would
|
5
|
+
# require a very large number of requests. Using a Payload object
|
6
|
+
# allows larger amounts of content to be saved at one time,
|
7
|
+
# significantly reducing the number of requests made.
|
8
|
+
class Payload < CodeFumes::API
|
9
|
+
PAYLOAD_CHARACTER_LIMIT = 4000 #:nodoc:
|
10
|
+
|
11
|
+
attr_reader :project_public_key, :project_private_key, :created_at
|
12
|
+
|
13
|
+
# Accepts +:public_key+, +:private_key+, and :content keys.
|
14
|
+
# +:content+ should also contain a key named +:commits+, with a list
|
15
|
+
# of commits and associated data. An example would be:
|
16
|
+
#
|
17
|
+
# {:public_key => "abC3", :private_key => "some-private-key",
|
18
|
+
# :content => {:commits => [{:identifier => "commit_identifer",
|
19
|
+
# :files_affected => 3, :any_metric_you_want => "value"}]}}
|
20
|
+
def initialize(options = {})
|
21
|
+
@project_public_key = options[:public_key]
|
22
|
+
@project_private_key = options[:private_key]
|
23
|
+
@content = options[:content]
|
24
|
+
end
|
25
|
+
|
26
|
+
# Saves instance to CodeFumes.com. After a successful save, the
|
27
|
+
# +created_at+ attribute will be populated with the timestamp the
|
28
|
+
# Payload was created.
|
29
|
+
#
|
30
|
+
# Returns +true+ if the Payload does not contain any content to be
|
31
|
+
# saved or the request was successful.
|
32
|
+
#
|
33
|
+
# Returns +false+ if the request failed.
|
34
|
+
def save
|
35
|
+
return true if empty_payload?
|
36
|
+
response = self.class.post("/projects/#{@project_public_key}/payloads", :query => {:payload => @content}, :basic_auth => {:username => @project_public_key, :password => @project_private_key})
|
37
|
+
|
38
|
+
case response.code
|
39
|
+
when 201
|
40
|
+
@created_at = response['payload']['created_at']
|
41
|
+
true
|
42
|
+
else
|
43
|
+
false
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# +save+ requests are made with a standard POST request (not a
|
48
|
+
# multi-part POST), so the request size is limited by the
|
49
|
+
# application server. The current configuration on CodeFumes.com
|
50
|
+
# limits requests to approximately 8,000 bytes (a little over). In
|
51
|
+
# order to simplify dealing with these constraints, without
|
52
|
+
# requiring a multi-part POST request, +prepare+ can be used to
|
53
|
+
# "chunk" up the data into Payloads which do not exceed this limit.
|
54
|
+
#
|
55
|
+
# Returns collection of payload objects which fall into the
|
56
|
+
# constraints of a individual payload (ie: length of raw request,
|
57
|
+
# et cetera).
|
58
|
+
#--
|
59
|
+
# TODO: Clean up how the size of the request is constrained, this
|
60
|
+
# is pretty hackish right now (basically guesses how many
|
61
|
+
# characters would be added when HTTParty wraps the content in XML.
|
62
|
+
def self.prepare(data = {})
|
63
|
+
return [] if data.nil? || data.empty?
|
64
|
+
raw_payload = data.dup
|
65
|
+
|
66
|
+
public_key = raw_payload.delete(:public_key)
|
67
|
+
raise ArgumentError, "No public key provided" if public_key.nil?
|
68
|
+
|
69
|
+
private_key = raw_payload.delete(:private_key)
|
70
|
+
|
71
|
+
if raw_payload[:content].nil? || raw_payload[:content][:commits].nil?
|
72
|
+
raise ArgumentError, "No commits key provided"
|
73
|
+
end
|
74
|
+
|
75
|
+
content = raw_payload[:content][:commits]
|
76
|
+
initial_chunks = {:on_deck => [], :prepared => []}
|
77
|
+
|
78
|
+
# TODO: Clean this up
|
79
|
+
chunked = content.inject(initial_chunks) do |chunks, new_commit|
|
80
|
+
if chunks[:on_deck].to_s.length + new_commit.to_s.length >= PAYLOAD_CHARACTER_LIMIT
|
81
|
+
chunks[:prepared] << chunks[:on_deck]
|
82
|
+
chunks[:on_deck] = [new_commit]
|
83
|
+
elsif new_commit == content.last
|
84
|
+
chunks[:on_deck] << new_commit
|
85
|
+
chunks[:prepared] << chunks[:on_deck]
|
86
|
+
chunks[:on_deck] = []
|
87
|
+
else
|
88
|
+
chunks[:on_deck] << new_commit
|
89
|
+
end
|
90
|
+
chunks
|
91
|
+
end
|
92
|
+
|
93
|
+
chunked[:prepared].map do |raw_content|
|
94
|
+
Payload.new(:public_key => public_key, :private_key => private_key, :content => {:commits => raw_content})
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
99
|
+
def empty_payload?
|
100
|
+
@content.empty? || @content[:commits].nil? || @content[:commits].blank?
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|