diff --git a/bin/postmortem b/bin/postmortem new file mode 100755 index 0000000..c8e73f6 --- /dev/null +++ b/bin/postmortem @@ -0,0 +1,10 @@ +#!/usr/bin/env -S /usr/bin/sbcl --dynamic-space-size 4096 --script + +(let ((quicklisp-init (merge-pathnames "quicklisp/setup.lisp" + (user-homedir-pathname)))) + (when (probe-file quicklisp-init) + (load quicklisp-init))) + +(ql:quickload :forgerie) + +(forgerie-core:postmortem :phabricator :gitlab) diff --git a/forgerie.asd b/forgerie.asd index a7322cc..b686471 100644 --- a/forgerie.asd +++ b/forgerie.asd @@ -1,37 +1,40 @@ (asdf:defsystem forgerie :description "Adapter between different software forges" :version "0.1" :maintainer "Open Tech Strategies" :author "Open Tech Strategies" :serial t :components ((:module "src/main" :components ((:module "core" :components ((:file "package") (:file "base") (:file "user") (:file "project") (:file "vc-repository") (:file "ticket") (:file "merge-request") (:file "snippet") (:file "utils") (:file "errors") - (:file "run"))) + (:file "run") + (:file "postmortem"))) (:module "phabricator" :components ((:file "package") (:file "utils") (:file "base") - (:file "import"))) + (:file "import") + (:file "postmortem"))) (:module "gitlab" :components ((:file "package") (:file "utils") (:file "base") - (:file "export"))))) + (:file "export") + (:file "postmortem"))))) (:module "config" :components ((:file "config")))) :depends-on (:cl-mysql :drakma :jsown :cl-ppcre :cl-csv :cl-fad :ironclad)) diff --git a/src/main/core/errors.lisp b/src/main/core/errors.lisp index b878c75..ade330e 100644 --- a/src/main/core/errors.lisp +++ b/src/main/core/errors.lisp @@ -1,40 +1,42 @@ (in-package #:forgerie-core) (defvar *log-mapping-errors* t) +(defgeneric display-mapping-error (error-type object-id description)) + (defstruct mapping-error error-type object-id description) (defvar *mapping-errors* nil) (defun mapping-errors-file () (format nil "~A/errors" *working-directory*)) (defun mapping-errors () (or *mapping-errors* (setf *mapping-errors* (when (probe-file (mapping-errors-file)) (with-open-file (str (mapping-errors-file)) (read str)))))) (defun add-mapping-error (error-type object-id description) (when (and *log-mapping-errors* (not (find-if (lambda (mapping-error) (and (equal (mapping-error-error-type mapping-error) error-type) (equal (mapping-error-object-id mapping-error) object-id))) (mapping-errors)))) (setf *mapping-errors* (cons (make-mapping-error :error-type error-type :object-id object-id :description description) (mapping-errors))) (with-open-file (str (mapping-errors-file) :direction :output :if-exists :supersede) (format str "~S" (mapping-errors))))) diff --git a/src/main/core/package.lisp b/src/main/core/package.lisp index bb51ef5..e534797 100644 --- a/src/main/core/package.lisp +++ b/src/main/core/package.lisp @@ -1,48 +1,51 @@ (defpackage #:forgerie-core (:use :cl) (:export ; run.lisp #:run + ; postmortem.lisp + #:postmortem #:system-postmortem + ; base.lisp #:*working-directory* #:import-forge #:export-forge #:make-file #:file-id #:file-name #:file-mimetype #:file-location #:file-size #:make-commit #:commit-sha #:commit #:commit-parsed-comment #:make-patch #:patch-diff #:patch #:make-branch #:branch-name #:branch-commit #:make-note #:note-text #:note-author #:note-date #:note-id ; user.lisp #:make-user #:user-username #:user-name #:user-emails #:make-email #:email-address #:email-is-primary #:user-primary-email #:user-admin #:user-avatar ; project.lisp #:make-project #:project-name #:project-tags ; ticket.lisp #:make-ticket #:ticket-id #:ticket-projects #:ticket-title #:ticket-notes #:ticket-author #:ticket-description #:ticket-date #:ticket-type #:ticket #:ticket-priority #:ticket-assignee #:ticket-confidential #:ticket-linked-tickets #:ticket-subscribers ; vc-repository.lisp #:make-vc-repository #:vc-repository-name #:vc-repository-slug #:vc-repository-primary-projects #:vc-repository-projects #:vc-repository-git-location #:vc-repository-commits ; snippet.lisp #:make-snippet #:snippet-id #:snippet-title #:snippet-files #:snippet-notes #:snippet-author #:snippet ; merge-request.lisp #:make-merge-request #:merge-request-id #:merge-request-vc-repository #:merge-request-title #:merge-request-description #:merge-request-source-branch #:merge-request-target-branch #:merge-request-changes #:merge-request-patch #:merge-request-type #:merge-request-notes #:merge-request-author #:merge-request-date #:merge-request #:make-merge-request-change #:merge-request-change-change #:merge-request-change-comments #:make-merge-request-change-comment #:merge-request-change-comment-line #:merge-request-change-comment-text #:merge-request-change-comment-replies #:merge-request-change-comment-author #:merge-request-change-comment-file #:merge-request-change-comment-date ; errors.lisp - #:add-mapping-error #:*log-mapping-errors* + #:add-mapping-error #:*log-mapping-errors* #:display-mapping-error ; utils.lisp #:vc-repositories-with-primary-project #:git-cmd #:*debug*)) diff --git a/src/main/core/postmortem.lisp b/src/main/core/postmortem.lisp new file mode 100644 index 0000000..7fde73a --- /dev/null +++ b/src/main/core/postmortem.lisp @@ -0,0 +1,13 @@ +(in-package #:forgerie-core) + +(defgeneric system-postmortem (system)) + +(defun postmortem (&rest systems) + (mapcar #'system-postmortem systems) + (mapcar + (lambda (mapping-error) + (display-mapping-error + (mapping-error-error-type mapping-error) + (mapping-error-object-id mapping-error) + (mapping-error-description mapping-error))) + (reverse (mapping-errors)))) diff --git a/src/main/gitlab/postmortem.lisp b/src/main/gitlab/postmortem.lisp new file mode 100644 index 0000000..61dbc30 --- /dev/null +++ b/src/main/gitlab/postmortem.lisp @@ -0,0 +1,25 @@ +(in-package #:forgerie-gitlab) + +(defmethod forgerie-core:system-postmortem ((system (eql :gitlab))) + (format t "Doing gitlab's postmortem~%")) + +(defmethod forgerie-core:display-mapping-error ((error (eql :linked-ticket-not-found)) object-id description) + (format t "Ticket ~A not found, so can't link: ~A~%" object-id description)) + +(defmethod forgerie-core:display-mapping-error ((error (eql :gitlab-repository-has-no-projects)) object-id description) + (format t "VC Repository ~A has no primary projects, so creating one.~%" object-id)) + +(defmethod forgerie-core:display-mapping-error ((error (eql :gitlab-ticket-assigned-to-default)) object-id description) + (format t "~A~%" description)) + +(defmethod forgerie-core:display-mapping-error ((error (eql :gitlab-ticket-assigned-to-multiple)) object-id description) + (format t "Ticket ~A assigned to multiple repositories, so can't assign~%" object-id)) + +(defmethod forgerie-core:display-mapping-error ((error (eql :gitlab-merge-request-not-assignable)) object-id description) + (format t "Merge Request with id ~A can't be assigned to a repository~%" object-id)) + +(defmethod forgerie-core:display-mapping-error ((error (eql :user-avatar-too-big)) object-id description) + (format t "~A~%" description)) + +(defmethod forgerie-core:display-mapping-error ((error (eql :gitlab-snippet-empty)) object-id description) + (format t "~A~%" description)) diff --git a/src/main/phabricator/postmortem.lisp b/src/main/phabricator/postmortem.lisp new file mode 100644 index 0000000..898739e --- /dev/null +++ b/src/main/phabricator/postmortem.lisp @@ -0,0 +1,38 @@ +(in-package #:forgerie-phabricator) + +(defmethod forgerie-core:system-postmortem ((system (eql :phabricator))) + (initialize) + (format t "Doing phab's postmortem~%") + (mapcar + (lambda (override) + (format t "Project '~A' assigned as the primary project to repository '~A'~%" + (getf override :name) + (getf override :repository))) + *project-assignment-overrides*) + (mapcar + (lambda (rev-id) + (let + ((rev (get-revision rev-id))) + (format t "Revision ~A skipped due to configuration (status: ~A)~%" rev-id (differential-revision-status rev)))) + *revisions-to-skip*) + (mapcar + (lambda (paste-id) + (format t "Paste ~A skipped due to configuation~%" paste-id)) + *pastes-to-skip*) + (mapcar + (lambda (user-override) + (format t "User ~A updated with data ~S~%" (getf user-override :key) (getf user-override :data))) + *user-overrides*) + (mapcar + (lambda (repository-override) + (let + ((repository (get-repository-by-id (getf repository-override :key)))) + (format t "Repository ~A ~A~%" + (repository-name repository) + (case (getf repository-override :action) + (:update + (format nil "updated with data ~A" (getf repository-override :data))) + (:skip + "skipped"))))) + *repository-overrides*) + (format t "---------------------~%"))