summaryrefslogtreecommitdiff
path: root/lib/gitlab/data_builder
diff options
context:
space:
mode:
authorLin Jen-Shin <godfat@godfat.org>2016-08-04 23:44:27 +0800
committerLin Jen-Shin <godfat@godfat.org>2016-08-04 23:44:27 +0800
commit984367f957c8f8d02fa82b08817e2f2f318c6bff (patch)
tree6f18804966e10c58473094c94cb8c2a0626d8065 /lib/gitlab/data_builder
parent80671bf75cdac3f50615253b058fa04da6235a4f (diff)
downloadgitlab-ce-984367f957c8f8d02fa82b08817e2f2f318c6bff.tar.gz
Move those builders to their own namespace, feedback:
https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/5620#note_13540099
Diffstat (limited to 'lib/gitlab/data_builder')
-rw-r--r--lib/gitlab/data_builder/build_data_builder.rb67
-rw-r--r--lib/gitlab/data_builder/note_data_builder.rb75
-rw-r--r--lib/gitlab/data_builder/push_data_builder.rb95
3 files changed, 237 insertions, 0 deletions
diff --git a/lib/gitlab/data_builder/build_data_builder.rb b/lib/gitlab/data_builder/build_data_builder.rb
new file mode 100644
index 00000000000..5175645e238
--- /dev/null
+++ b/lib/gitlab/data_builder/build_data_builder.rb
@@ -0,0 +1,67 @@
+module Gitlab
+ module DataBuilder
+ module BuildDataBuilder
+ module_function
+
+ def build(build)
+ project = build.project
+ commit = build.pipeline
+ user = build.user
+
+ data = {
+ object_kind: 'build',
+
+ ref: build.ref,
+ tag: build.tag,
+ before_sha: build.before_sha,
+ sha: build.sha,
+
+ # TODO: should this be not prefixed with build_?
+ # Leaving this way to have backward compatibility
+ build_id: build.id,
+ build_name: build.name,
+ build_stage: build.stage,
+ build_status: build.status,
+ build_started_at: build.started_at,
+ build_finished_at: build.finished_at,
+ build_duration: build.duration,
+ build_allow_failure: build.allow_failure,
+
+ # TODO: do we still need it?
+ project_id: project.id,
+ project_name: project.name_with_namespace,
+
+ user: {
+ id: user.try(:id),
+ name: user.try(:name),
+ email: user.try(:email),
+ },
+
+ commit: {
+ id: commit.id,
+ sha: commit.sha,
+ message: commit.git_commit_message,
+ author_name: commit.git_author_name,
+ author_email: commit.git_author_email,
+ status: commit.status,
+ duration: commit.duration,
+ started_at: commit.started_at,
+ finished_at: commit.finished_at,
+ },
+
+ repository: {
+ name: project.name,
+ url: project.url_to_repo,
+ description: project.description,
+ homepage: project.web_url,
+ git_http_url: project.http_url_to_repo,
+ git_ssh_url: project.ssh_url_to_repo,
+ visibility_level: project.visibility_level
+ },
+ }
+
+ data
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/data_builder/note_data_builder.rb b/lib/gitlab/data_builder/note_data_builder.rb
new file mode 100644
index 00000000000..12ae1b99f9c
--- /dev/null
+++ b/lib/gitlab/data_builder/note_data_builder.rb
@@ -0,0 +1,75 @@
+module Gitlab
+ module DataBuilder
+ module NoteDataBuilder
+ module_function
+
+ # Produce a hash of post-receive data
+ #
+ # For all notes:
+ #
+ # data = {
+ # object_kind: "note",
+ # user: {
+ # name: String,
+ # username: String,
+ # avatar_url: String
+ # }
+ # project_id: Integer,
+ # repository: {
+ # name: String,
+ # url: String,
+ # description: String,
+ # homepage: String,
+ # }
+ # object_attributes: {
+ # <hook data for note>
+ # }
+ # <note-specific data>: {
+ # }
+ # note-specific data is a hash with one of the following keys and contains
+ # the hook data for that type.
+ # - commit
+ # - issue
+ # - merge_request
+ # - snippet
+ #
+ def build(note, user)
+ project = note.project
+ data = build_base_data(project, user, note)
+
+ if note.for_commit?
+ data[:commit] = build_data_for_commit(project, user, note)
+ elsif note.for_issue?
+ data[:issue] = note.noteable.hook_attrs
+ elsif note.for_merge_request?
+ data[:merge_request] = note.noteable.hook_attrs
+ elsif note.for_snippet?
+ data[:snippet] = note.noteable.hook_attrs
+ end
+
+ data
+ end
+
+ def build_base_data(project, user, note)
+ base_data = {
+ object_kind: "note",
+ user: user.hook_attrs,
+ project_id: project.id,
+ project: project.hook_attrs,
+ object_attributes: note.hook_attrs,
+ # DEPRECATED
+ repository: project.hook_attrs.slice(:name, :url, :description, :homepage)
+ }
+
+ base_data[:object_attributes][:url] = Gitlab::UrlBuilder.build(note)
+ base_data
+ end
+
+ def build_data_for_commit(project, user, note)
+ # commit_id is the SHA hash
+ commit = project.commit(note.commit_id)
+ commit.hook_attrs
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/data_builder/push_data_builder.rb b/lib/gitlab/data_builder/push_data_builder.rb
new file mode 100644
index 00000000000..f0cad51dd36
--- /dev/null
+++ b/lib/gitlab/data_builder/push_data_builder.rb
@@ -0,0 +1,95 @@
+module Gitlab
+ module DataBuilder
+ module PushDataBuilder
+ module_function
+
+ # Produce a hash of post-receive data
+ #
+ # data = {
+ # before: String,
+ # after: String,
+ # ref: String,
+ # user_id: String,
+ # user_name: String,
+ # user_email: String
+ # project_id: String,
+ # repository: {
+ # name: String,
+ # url: String,
+ # description: String,
+ # homepage: String,
+ # },
+ # commits: Array,
+ # total_commits_count: Fixnum
+ # }
+ #
+ def build(project, user, oldrev, newrev, ref, commits = [], message = nil)
+ commits = Array(commits)
+
+ # Total commits count
+ commits_count = commits.size
+
+ # Get latest 20 commits ASC
+ commits_limited = commits.last(20)
+
+ # For performance purposes maximum 20 latest commits
+ # will be passed as post receive hook data.
+ commit_attrs = commits_limited.map do |commit|
+ commit.hook_attrs(with_changed_files: true)
+ end
+
+ type = Gitlab::Git.tag_ref?(ref) ? 'tag_push' : 'push'
+
+ # Hash to be passed as post_receive_data
+ data = {
+ object_kind: type,
+ event_name: type,
+ before: oldrev,
+ after: newrev,
+ ref: ref,
+ checkout_sha: checkout_sha(project.repository, newrev, ref),
+ message: message,
+ user_id: user.id,
+ user_name: user.name,
+ user_email: user.email,
+ user_avatar: user.avatar_url,
+ project_id: project.id,
+ project: project.hook_attrs,
+ commits: commit_attrs,
+ total_commits_count: commits_count,
+ # DEPRECATED
+ repository: project.hook_attrs.slice(:name, :url, :description, :homepage,
+ :git_http_url, :git_ssh_url, :visibility_level)
+ }
+
+ data
+ end
+
+ # This method provide a sample data generated with
+ # existing project and commits to test webhooks
+ def build_sample(project, user)
+ commits = project.repository.commits(project.default_branch, limit: 3)
+ ref = "#{Gitlab::Git::BRANCH_REF_PREFIX}#{project.default_branch}"
+ build(project, user, commits.last.id, commits.first.id, ref, commits)
+ end
+
+ def checkout_sha(repository, newrev, ref)
+ # Checkout sha is nil when we remove branch or tag
+ return if Gitlab::Git.blank_ref?(newrev)
+
+ # Find sha for tag, except when it was deleted.
+ if Gitlab::Git.tag_ref?(ref)
+ tag_name = Gitlab::Git.ref_name(ref)
+ tag = repository.find_tag(tag_name)
+
+ if tag
+ commit = repository.commit(tag.target)
+ commit.try(:sha)
+ end
+ else
+ newrev
+ end
+ end
+ end
+ end
+end