Skip to content

Commit

Permalink
Fetchin' live MR vales from GitLab API
Browse files Browse the repository at this point in the history
  • Loading branch information
notjosh authored and bigkraig committed Apr 9, 2019
1 parent e6410b8 commit 91ef63a
Show file tree
Hide file tree
Showing 5 changed files with 413 additions and 25 deletions.
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -133,6 +133,7 @@
"commander": "^2.18.0",
"debug": "^4.1.1",
"get-stdin": "^6.0.0",
"gitlab": "^5.0.0-rc.11",
"http-proxy-agent": "^2.1.0",
"https-proxy-agent": "^2.2.1",
"hyperlinker": "^1.0.0",
Expand Down
138 changes: 138 additions & 0 deletions source/dsl/GitLabDSL.ts
@@ -0,0 +1,138 @@
export interface GitLabUser {
id: number
name: string
username: string
state: "active"
avatar_url: string | null
web_url: string
}

export interface GitLabMRDSLBase {
/** */
id: number

/** */
iid: number

/** */
project_id: number

/** */
title: string

/** */
description: string

/** */
state: "closed" | "open" | "locked" | "merged"

/** */
created_at: string

/** */
updated_at: string

target_branch: string
source_branch: string
upvotes: number
downvotes: number

author: GitLabUser
user: {
can_merge: boolean
}
assignee: GitLabUser
source_project_id: number
target_project_id: number
labels: string[]
work_in_progress: boolean
milestone: {
id: number
iid: number
project_id: number
title: string
description: string
state: "closed"
created_at: string
updated_at: string
due_date: string
start_date: string
web_url: string
}
merge_when_pipeline_succeeds: boolean
merge_status: "can_be_merged"
merge_error: null | null
sha: string
merge_commit_sha: string | null
user_notes_count: number
discussion_locked: null | null
should_remove_source_branch: boolean
force_remove_source_branch: boolean
allow_collaboration: boolean
allow_maintainer_to_push: boolean
web_url: string
time_stats: {
time_estimate: number
total_time_spent: number
human_time_estimate: number | null
human_total_time_spent: number | null
}
}

export interface GitLabMRDSL extends GitLabMRDSLBase {
squash: boolean
subscribed: boolean
changes_count: string
merged_by: GitLabUser
merged_at: string
closed_by: GitLabUser | null
closed_at: string | null
latest_build_started_at: string
latest_build_finished_at: string
first_deployed_to_production_at: string | null
pipeline: {
id: number
sha: string
ref: string
status: "success"
web_url: string
}
diff_refs: {
base_sha: string
head_sha: string
start_sha: string
}
diverged_commits_count: number
rebase_in_progress: boolean
approvals_before_merge: null | null
}

export interface GitLabMRChangeDSL {
old_path: string
new_path: string
a_mode: string
b_mode: string
diff: string
new_file: boolean
renamed_file: boolean
deleted_file: boolean
}

export interface GitLabMRChangesDSL extends GitLabMRDSLBase {
changes: GitLabMRChangeDSL[]
}

export interface GitLabMRCommitDSL {
id: string
short_id: string
created_at: string
parent_ids: string[]
title: string
message: string
author_name: string
author_email: string
authored_date: string
committer_name: string
committer_email: string
committed_date: string
}
67 changes: 46 additions & 21 deletions source/platforms/GitLab.ts
@@ -1,7 +1,8 @@
import GitLabAPI from "./gitlab/GitLabAPI"
import { Platform, Comment } from "./platform"
import { readFileSync } from "fs"
import { GitDSL } from "../dsl/GitDSL"
import { GitDSL, GitJSONDSL } from "../dsl/GitDSL"
import { GitCommit } from "../dsl/Commit"

class GitLab implements Platform {
public readonly name: string
Expand All @@ -11,33 +12,57 @@ class GitLab implements Platform {
}

async getReviewInfo(): Promise<any> {
return {}
return this.api.getPullRequestInfo()
}

async getPlatformReviewDSLRepresentation(): Promise<any> {
return {}
}

async getPlatformGitRepresentation(): Promise<GitDSL> {
return {
modified_files: [],
created_files: [],
deleted_files: [],
diffForFile: async () => ({ before: "", after: "", diff: "", added: "", removed: "" }),
structuredDiffForFile: async () => ({ chunks: [] }),
JSONDiffForFile: async () => ({} as any),
JSONPatchForFile: async () => ({} as any),
commits: [
{
sha: "123",
author: { name: "1", email: "1", date: "1" },
committer: { name: "1", email: "1", date: "1" },
message: "456",
tree: { sha: "123", url: "123" },
url: "123",
async getPlatformGitRepresentation(): Promise<GitJSONDSL> {
const changes = await this.api.getMergeRequestChanges()
const commits = await this.api.getMergeRequestCommits()

const mappedCommits: GitCommit[] = commits.map(commit => {
return {
sha: commit.id,
author: {
name: commit.author_name,
email: commit.author_email,
date: commit.authored_date,
},
committer: {
name: commit.committer_name,
email: commit.committer_email,
date: commit.committed_date,
},
],
linesOfCode: async () => 0,
message: commit.message,
parents: commit.parent_ids,
url: `${this.api.projectURL}/commit/${commit.id}`,
//url: `${this.api.mergeRequestURL}/diffs?commit_id=${commit.id}`,
tree: null,
}
})

// XXX: does "renamed_file"/move count is "delete/create", or "modified"?
const modified_files: string[] = changes
.filter(change => change.new_file === false && change.deleted_file == false)
.map(change => change.new_path)
const created_files: string[] = changes.filter(change => change.new_file === true).map(change => change.new_path)
const deleted_files: string[] = changes
.filter(change => change.deleted_file === true)
.map(change => change.new_path)

return {
modified_files,
created_files,
deleted_files,
// diffForFile: async () => ({ before: "", after: "", diff: "", added: "", removed: "" }),
// structuredDiffForFile: async () => ({ chunks: [] }),
// JSONDiffForFile: async () => ({} as any),
// JSONPatchForFile: async () => ({} as any),
commits: mappedCommits,
// linesOfCode: async () => 0,
}
}

Expand Down
68 changes: 68 additions & 0 deletions source/platforms/gitlab/GitLabAPI.ts
@@ -1,15 +1,83 @@
import { RepoMetaData } from "../../dsl/BitBucketServerDSL"
import { api as fetch } from "../../api/fetch"
import { GitLabMRDSL, GitLabMRChangesDSL, GitLabMRChangeDSL, GitLabMRCommitDSL } from "../../dsl/GitLabDSL"

import { Gitlab } from "gitlab"
// const Gitlab = require("gitlab").default

export type GitLabAPIToken = string

class GitLabAPI {
fetch: typeof fetch

private pr: GitLabMRDSL | undefined

// https://github.com/jdalrymple/node-gitlab/issues/257
private api: any //typeof Gitlab

constructor(public readonly repoMetadata: RepoMetaData, public readonly token: GitLabAPIToken) {
// This allows Peril to DI in a new Fetch function
// which can handle unique API edge-cases around integrations
this.fetch = fetch

// Type 'Mapper<typeof import("/Users/joshua/dev/ext/danger-js/node_modules/gitlab/dist/services/index"), "Groups" | "GroupAccessRequests" | "GroupBadges" | "GroupCustomAttributes" | "GroupIssueBoards" | ... 77 more ... | "Wikis">' is not assignable to type
// 'Bundle<typeof import("/Users/joshua/dev/ext/danger-js/node_modules/gitlab/dist/services/index"), "Groups" | "GroupAccessRequests" | "GroupBadges" | "GroupCustomAttributes" | "GroupIssueBoards" | ... 77 more ... | "Wikis">'.
// Type 'Mapper<typeof import("/Users/joshua/dev/ext/danger-js/node_modules/gitlab/dist/services/index"), "Groups" | "GroupAccessRequests" | "GroupBadges" | "GroupCustomAttributes" | "GroupIssueBoards" | ... 77 more ... | "Wikis">' provides no match for the signature
// 'new (options?: any): Mapper<typeof import("/Users/joshua/dev/ext/danger-js/node_modules/gitlab/dist/services/index"), "Groups" | "GroupAccessRequests" | "GroupBadges" | "GroupCustomAttributes" | ... 78 more ... | "Wikis">'.ts(2322)

const api = new Gitlab({
host: this.hostURL,
token,
})

this.api = api
}

get hostURL(): string {
return `https://${process.env["DANGER_GITLAB_HOST"]}`
}

get projectURL(): string {
return `${this.hostURL}/${this.repoMetadata.repoSlug}`
}

get mergeRequestURL(): string {
return `${this.projectURL}/merge_requests/${this.repoMetadata.pullRequestID}`
}

getPullRequestInfo = async (): Promise<GitLabMRDSL> => {
if (this.pr) {
return this.pr
}

console.log("[+] getPullRequestInfo")

return this.api.MergeRequests.show(this.repoMetadata.repoSlug, this.repoMetadata.pullRequestID)

// const repo = this.repoMetadata.repoSlug
// const prID = this.repoMetadata.pullRequestID
// const res = await this.get(`repos/${repo}/pulls/${prID}`)
// const prDSL = (await res.json()) as GitLabMRDSL
// this.pr = prDSL

// if (res.ok) {
// return prDSL
// } else {
// throw `Could not get PR Metadata for repos/${repo}/pulls/${prID}`
// }
}

getMergeRequestChanges = async (): Promise<GitLabMRChangeDSL[]> => {
const pr: GitLabMRChangesDSL = await this.api.MergeRequests.changes(
this.repoMetadata.repoSlug,
this.repoMetadata.pullRequestID
)

return pr.changes
}

getMergeRequestCommits = async (): Promise<GitLabMRCommitDSL[]> => {
return this.api.MergeRequests.commits(this.repoMetadata.repoSlug, this.repoMetadata.pullRequestID)
}
}

Expand Down

0 comments on commit 91ef63a

Please sign in to comment.