Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
Signed-off-by: Nicolas Lamirault <nicolas.lamirault@gmail.com>
  • Loading branch information
nlamirault committed Jun 4, 2015
2 parents f28c8d8 + 463fe06 commit 9401c9b
Show file tree
Hide file tree
Showing 10 changed files with 262 additions and 62 deletions.
7 changes: 7 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# emacs-gitlab ChangeLog

## Version 0.5 (06/04/2015)

- ``FIX`` Unit tests on issues API
- ``FIX`` List projects without page parameters
- ``#20``: List all issues and projects (pagination refactoring) (Thanks [marcinant][])
- ``#19``: Feature/extend gitlab mode (Thanks [marcinant][])

## Version 0.4 (05/29/2015)

- Initial support for Users API (Thanks [marcinant][])
Expand Down
22 changes: 13 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,20 @@ management. Install it and retrieve dependencies :

* Setup your Gitlab informations :

$ export GITLAB_HOST="http://gitlab.foo.com"
$ export GITLAB_USERNAME="foo"
$ export GITLAB_PASSWORD="bar"
$ export GITLAB_TOKEN_ID="xxxxxxxxxxxxxx"
$ export GITLAB_PROJECT_ID=111222
$ export GITLAB_PROJECT_NAME="myproject"
$ export GITLAB_PROJECT_DESCRIPTION="a project description"
$ export GITLAB_ISSUE_ID=145645
$ export GITLAB_ISSUE_TITLE="the issue title"
$ cat $HOME/.emacs-gitlab.rc
#!/bin/bash
export GITLAB_HOST="https://gitlab.com"
export GITLAB_USERNAME="yourusername"
export GITLAB_PASSWORD="yourpassword"
export GITLAB_PROJECT_ID=111222
export GITLAB_PROJECT_NAME="myproject"
export GITLAB_PROJECT_DESCRIPTION="a project description"
export GITLAB_ISSUE_ID=145645
export GITLAB_ISSUE_TITLE="the issue title"

* Launch unit tests :

$ . $HOME/.emacs-gitlab.rc
$ make clean test


Expand All @@ -104,6 +106,8 @@ See [LICENSE](LICENSE).

Nicolas Lamirault <nicolas.lamirault@gmail.com>



[emacs-gitlab]: https://github.com/nlamirault/emacs-gitlab
[badge-license]: https://img.shields.io/badge/license-GPL_2-green.svg?style=flat
[LICENSE]: https://github.com/nlamirault/emacs-gitlab/blob/master/LICENSE
Expand Down
81 changes: 61 additions & 20 deletions gitlab-issues.el
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,32 @@
(require 'gitlab-utils)


(defun gitlab-list-issues ()
(defun gitlab-list-issues (page per-page)
"Get all issues created by authenticated user.
STATE Return all issues or just those that are opened or closed
LABELS - Comma-separated list of label names"
PAGE: current page number
PER-PAGE: number of items on page max 100"
(let ((params '()))
;; (when state
;; (add-to-list params (cons "state" state)))
;; (when labels
;; (add-to-list params (cons "labels" labels)))
(perform-gitlab-request "GET" "issues" params 200)))

(add-to-list 'params (cons 'per_page (number-to-string per-page)))
(add-to-list 'params (cons 'page (number-to-string page)))
(perform-gitlab-request "GET"
"issues"
params
200)))

(defun gitlab-list-all-issues ()
"Get a list of all issues."
(interactive)
(let* ((page 1)
(per-page 100)
(issues)
(all-issues (gitlab-list-issues page per-page))
(all-issues-count (length all-issues)))
(while (>= all-issues-count (* page per-page))
(setq issues (gitlab-list-issues page per-page))
(setq all-issues (vconcat all-issues issues))
(setq all-issues-count (length all-issues))
(setq page (1+ page)))
all-issues))

(defun gitlab--get-issue-uri (project-id issue-id)
"Retrieve URI to retrieve an issue.
Expand All @@ -52,17 +67,42 @@ ISSUE-ID : The ID of a project issue"
"/issues/"
issue-id))

(defun gitlab-list-project-issues (project-id)
(defun gitlab-list-project-issues (project-id &optional page per-page)
"Get a list of project issues.
PROJECT-ID : The ID of a project
PAGE: current page number
PER-PAGE: number of items on page max 100"
(let ((params '()))
(when page
(add-to-list 'params (cons 'per_page (number-to-string per-page))))
(when per-page
(add-to-list 'params (cons 'page (number-to-string page))))
(perform-gitlab-request "GET"
(s-concat "projects/"
(url-hexify-string
(format "%s" project-id))
"/issues")
params
200)))

(defun gitlab-list-all-project-issues (project-id &optional page per-page)
"Get a list of all PROJECT-ID issues.
PROJECT-ID : The ID of a project
PAGE: current page number
PER-PAGE: number of items on page max 100"
(interactive)
(let* ((page 1)
(per-page 100)
(issues)
(all-issues (gitlab-list-project-issues project-id page per-page))
(all-issues-count (length all-issues)))
(while (>= all-issues-count (* page per-page))
(setq issues (gitlab-list-project-issues project-id page per-page))
(setq all-issues (vconcat all-issues issues))
(setq all-issues-count (length all-issues))
(setq page (1+ page)))
all-issues))

PROJECT-ID : The ID of a project"
(perform-gitlab-request "GET"
(s-concat "projects/"
(url-hexify-string
(format "%s" project-id))
"/issues")
nil
200))

(defun gitlab-get-issue (project-id issue-id)
"Gets a single project issue.
Expand Down Expand Up @@ -109,10 +149,11 @@ LABELS comma-separated list label names"
"Create a project issue.
PROJECT-ID the ID or NAMESPACE%2FPROJECT_NAME of a project
ISSUE-ID : The ID of a project issue
TITLE issue title
DESCRIPTION issue description
ASSIGNEE assignee ID
MILESTONE milestone ID
ASSIGNEE-ID assignee ID
MILESTONE-ID milestone ID
LABELS comma-separated list label names"
(lwarn '(gitlab) :debug "UPDATE ISSUE in project: %s\n" project-id)
(perform-gitlab-request "PUT"
Expand Down
117 changes: 106 additions & 11 deletions gitlab-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

(require 'browse-url)
(require 'tabulated-list)
(require 'vc-git)

;; Gitlab library

Expand All @@ -41,30 +42,124 @@
(interactive)
(message (concat "Current ID is: " (tabulated-list-get-id))))


(defun project-make-button (text &rest props)
"Make button with TEXT propertized with PROPS."
(let ((button-text (if (display-graphic-p)
text
(concat "[" text "]")))
(button-face (if (display-graphic-p)
'(:box (:line-width 2 :color "dark grey")
:background "light grey"
:foreground "black")
'link)))
(apply 'insert-text-button button-text
'face button-face
'follow-link t
props)))

;; Projects
(defun gitlab-project-clone-button-action (button)
"Action for BUTTON."
(interactive)

(let* ((project (gitlab-get-project (button-get button 'project-id)))
(name (assoc-default 'path project))
(repo (assoc-default 'ssh_url_to_repo project))
(target-dir (read-directory-name "Clone to directory:" (first query-replace-defaults))))

(if (file-directory-p (expand-file-name name target-dir))
(progn
(message "Target directory exists and is not empty. Trying to pull.")
(let ((default-directory (file-name-as-directory (expand-file-name name target-dir))))
(vc-git-command nil 0 nil "pull" repo)))
(progn
(make-directory name target-dir)
(vc-git-command nil 0 nil "clone" repo (file-name-as-directory (expand-file-name name target-dir)))))
(revert-buffer nil t)
(goto-char (point-min))))


(defun gitlab-goto-project ()
"Got to web page of the project."
(let ((project (tabulated-list-get-entry)))
(interactive)
(let* ((project (gitlab-get-project (tabulated-list-get-id))))
(browse-url (assoc-default 'web_url project))))

;;;###autoload
(defun gitlab-show-project-description (project)
"Doc string PROJECT."
(interactive)
(with-help-window (help-buffer)
(with-current-buffer standard-output
(let ((desc (assoc-default 'description project))
(homepage (assoc-default 'web_url project))
(id (assoc-default 'id project))
(status (number-to-string (assoc-default 'visibility_level project))))

(insert " Name: ")
(princ (assoc-default 'name project))
(princ "\n")
(insert " Path: ")
(princ (assoc-default 'path_with_namespace project))
(princ "\n\n")

(insert " Repository: ")
(princ (assoc-default 'ssh_url_to_repo project))
(insert "\n\n")

(insert " " (propertize "Status" 'font-lock-face 'bold) ": ")
(cond ((string= status "0")
(insert (propertize (capitalize "Private") 'font-lock-faces 'font-lock-builtin-face)))
((string= status "10")
(insert (propertize (capitalize "Internal") 'font-lock-faces 'font-lock-builtin-face)))
((string= status "20")
(insert (propertize (capitalize "Public") 'font-lock-faces 'font-lock-builtin-face))))
(insert " -- ")
(project-make-button
"Clone to / Pull"
'action 'gitlab-project-clone-button-action
'project-id id)

(insert "\n\n")


(insert " " (propertize "Summary" 'font-lock-face 'bold)
": " (if desc desc) "\n")

(when homepage
(insert " " (propertize "Homepage" 'font-lock-face 'bold) ": ")
(help-insert-xref-button homepage 'help-url homepage)
(insert "\n"))))))


(defun gitlab-describe-project (&optional button)
"Describe the current pproject.
If optional arg BUTTON is non-nil, describe its associated project."
(interactive)
(let ((project (gitlab-get-project (tabulated-list-get-id))))
(if project
(gitlab-show-project-description project)
(user-error "No project here"))))


>>>>>>> develop
(defun gitlab-show-projects ()
"Show Gitlab projects."
(interactive)
(pop-to-buffer "*Gitlab projects*" nil)
(gitlab-projects-mode)
(setq tabulated-list-entries
(create-projects-entries (gitlab-list-projects)))
(create-projects-entries (gitlab-list-all-projects)))
(tabulated-list-print t))

(defun create-projects-entries (projects)
"Create entries for 'tabulated-list-entries from PROJECTS."
(mapcar (lambda (p)

(let ((id (number-to-string (assoc-default 'id p)))
(owner (assoc-default 'owner p))
(owner (if (assoc-default 'owner p)
(assoc-default 'owner p)
(assoc-default 'namespace p)))
(namespace (assoc-default 'namespace p)))
(list id
(vector ;id
Expand All @@ -78,7 +173,9 @@

(defun gitlab-goto-issue ()
"Got to web page of the issue."
)
(interactive)
(let ((project (gitlab-get-project (elt (tabulated-list-get-entry) 1))))
(browse-url (concat (assoc-default 'web_url project) "/issues/" (tabulated-list-get-id)))))

(defun create-issues-entries (issues)
"Create entries for 'tabulated-list-entries from ISSUES."
Expand All @@ -88,6 +185,7 @@
(list id
(vector ;id
(assoc-default 'state i)
(format "%s" (assoc-default 'project_id i))
(assoc-default 'name author)
(assoc-default 'title i)))))
issues))
Expand All @@ -99,7 +197,7 @@
(pop-to-buffer "*Gitlab issues*" nil)
(gitlab-issues-mode)
(setq tabulated-list-entries
(create-issues-entries (gitlab-list-issues)))
(create-issues-entries (gitlab-list-all-issues)))
(tabulated-list-print t))


Expand All @@ -111,6 +209,7 @@
(let ((map (make-keymap)))
(define-key map (kbd "v") 'print-current-line-id)
(define-key map (kbd "w") 'gitlab-goto-project)
(define-key map (kbd "d") 'gitlab-describe-project)
map)
"Keymap for `gitlab-projects-mode' major mode.")

Expand Down Expand Up @@ -142,16 +241,12 @@
:group 'gitlab
(setq tabulated-list-format [;("ID" 5 t)
("State" 10 t)
("Project" 8 t)
("Author" 20 t)
("Title" 0 t)])
(setq tabulated-list-padding 2)
(setq tabulated-list-sort-key (cons "Title" nil))
(tabulated-list-init-header))






(provide 'gitlab-mode)
;;; gitlab-mode.el ends here

0 comments on commit 9401c9b

Please sign in to comment.