;;; vlocitemacs.el --- Vlocity Build Tool :: Emacs integration
|
|
|
|
;;; Commentary:
|
|
;;
|
|
;; Essentially the following commands are abstracted into elisp and made dynamic:
|
|
;;
|
|
;; vlocity packDeploy -propertyfile build.properties -job job.yaml -key VlocityUITemplate/Test-test
|
|
;; vlocity packExport -propertyfile build.properties -job job.yaml -key VlocityUITemplate/Test-test
|
|
;;
|
|
;;
|
|
;;; Code:
|
|
|
|
(require 'transient)
|
|
(require 'json)
|
|
|
|
|
|
(defvar vlo/org-usernames '()
|
|
"Auto-generated list of usernames from SFDX that are both authenticated and connected.")
|
|
|
|
(defvar vlo/default-environment-template "{
|
|
\"environments\": [
|
|
{
|
|
\"env\": \"default\",
|
|
\"username\": \"\",
|
|
\"job\": \"job.yaml\"
|
|
}
|
|
]
|
|
}" "Default template for creating the initial .vemacs file.")
|
|
|
|
(defvar vlo/project-file-name ".vemacs.json"
|
|
"The name of the VlocitEmacs configuration file.
|
|
|
|
This file exists for the purpose of locating the project folder as there is no
|
|
good way of knowing you are in the root vlocity project. It also contains the
|
|
list of environments to be used for deployments/exports.")
|
|
|
|
|
|
(defun vlo/generate-project-file ()
|
|
"Create the project file and append it to .gitignore if file exists."
|
|
(interactive)
|
|
(let* ((dir (read-directory-name "Choose Project Root: "))
|
|
(project-file (concat dir vlo/project-file-name))
|
|
(gitignore (concat dir ".gitignore")))
|
|
(with-temp-file project-file (insert vlo/default-environment-template))
|
|
(when (file-exists-p gitignore)
|
|
(append-to-file vlo/project-file-name nil gitignore))))
|
|
|
|
|
|
(defun vlo/get-org-list ()
|
|
"Get a list of authenticated orgs via SFDX cli and populate the `vlo/org-usernames' variable."
|
|
(interactive)
|
|
(let* ((temp-json-file
|
|
(make-temp-file "sfdx-org-list" nil ".json"
|
|
(shell-command-to-string "sfdx force:org:list --json")))
|
|
(json-object-type 'hash-table)
|
|
(json-array-type 'list)
|
|
(json-key-type 'string)
|
|
(json (json-read-file temp-json-file))
|
|
(result (gethash "result" json))
|
|
(orgs (gethash "nonScratchOrgs" result))
|
|
)
|
|
;; (message "%s" orgs)
|
|
(setq vlo/org-usernames '())
|
|
(dolist (org orgs)
|
|
(add-to-list 'vlo/org-usernames (gethash "username" org)))
|
|
)
|
|
)
|
|
|
|
;; (defun vlo/get-environment-list (&optional key)
|
|
;; "Get the list of org environment vars from within vlo/project-file-name JSON file with optional KEY to get a list of keys."
|
|
;; (let* ())
|
|
;; )
|
|
|
|
|
|
(defun vlo/getuser ()
|
|
"Prompt for sfdx username or use stored."
|
|
(interactive)
|
|
(let ((username (completing-read "SFDX User: " vlo/org-usernames nil t nil nil)))
|
|
(if (yes-or-no-p (format "Set \"%s\" as default for this project?" username))
|
|
;;insert username into project file
|
|
(progn
|
|
(with-temp-file (concat (vlo/project-path) vlo/project-file-name) (insert username))
|
|
(message "Default set to: %s" username)
|
|
)
|
|
(message "No default set"))))
|
|
|
|
|
|
|
|
(defun vlo/get-deployment-key ()
|
|
"Return the \"key\" used by vlocity to specify what to deploy/export."
|
|
(vlo/ensure-init-file)
|
|
(let ((path-list (delete "" (split-string (file-name-directory (buffer-file-name)) "/"))))
|
|
(format "%s/%s"
|
|
(nth (- (length path-list) 2) path-list)
|
|
(nth (- (length path-list) 1) path-list))))
|
|
|
|
(defun vlo/project-path ()
|
|
"Return path to the project file, or nil.
|
|
If project file exists in the current working directory, or a
|
|
parent directory recursively, return its path. Otherwise, return
|
|
nil."
|
|
(let ((dir (locate-dominating-file default-directory vlo/project-file-name)))
|
|
(unless dir
|
|
(error (concat "Error: cannot find " vlo/project-file-name)))
|
|
dir))
|
|
|
|
(defun vlo/in-project ()
|
|
"Asserts that you're currently inside a vlocity project."
|
|
(let ((dir (locate-dominating-file default-directory vlo/project-file-name)))
|
|
(if dir
|
|
t
|
|
nil)))
|
|
|
|
(defun leo/exec-process (cmd &optional comint)
|
|
"Execute a process running CMD and optionally pass COMINT as t to put buffer in `comint-mode'."
|
|
(let ((compilation-buffer-name-function
|
|
(lambda (mode)
|
|
(format "*exec-process*"))))
|
|
(message (concat "Running " cmd))
|
|
(compile cmd comint)))
|
|
|
|
|
|
|
|
|
|
(defun vlo/packExport ()
|
|
"Run the packExport command."
|
|
(interactive)
|
|
(if (and (vlo/in-project)
|
|
(file-exists-p (vlo/get-propertyfile-name))
|
|
(file-exists-p (vlo/get-jobfile-name)))
|
|
(leo/exec-process
|
|
(format "cd %s; vlocity packExport -sfdx.username %s -job %s -key %s"
|
|
(vlo/project-path)
|
|
(vlo/get-user)
|
|
(vlo/get-jobfile-name)
|
|
(vlo/get-deployment-key)))
|
|
(error (format "Error: cannot find either %s or %s" (vlo/get-propertyfile-name) (vlo/get-jobfile-name)))))
|
|
|
|
(defun vlo/packDeploy ()
|
|
"Run the packDeploy command."
|
|
(interactive)
|
|
(if (and (vlo/in-project)
|
|
(file-exists-p (vlo/get-propertyfile-name))
|
|
(file-exists-p (vlo/get-jobfile-name)))
|
|
(leo/exec-process
|
|
(format "cd %s; vlocity packDeploy -sfdx.username %s -job %s -key %s"
|
|
(vlo/project-path)
|
|
(vlo/get-user)
|
|
(vlo/get-jobfile-name)
|
|
(vlo/get-deployment-key)))
|
|
(error (format "Error: cannot find either %s or %s" (vlo/get-propertyfile-name) (vlo/get-jobfile-name)))))
|
|
|
|
(defun vlo/transient-action ()
|
|
"Dynamically choose which transient to show based on if currently in a project."
|
|
(interactive)
|
|
(if (vlo/in-project)
|
|
(vlo/transient-project-action)
|
|
(vlo/transient-init-action)))
|
|
|
|
(define-transient-command vlo/transient-init-action ()
|
|
"Vlocity Build Tool CLI Actions"
|
|
["Initialize"
|
|
("i" "Create .vemacs in project root" vlo/generate-project-file)]
|
|
)
|
|
|
|
(define-transient-command vlo/transient-project-action ()
|
|
"Vlocity Build Tool CLI Actions"
|
|
["Environments"
|
|
("a" "Add new org environment" vlo/transient-action)]
|
|
["Actions"
|
|
("e" "export" vlo/packExport)
|
|
("d" "deploy" vlo/packDeploy)])
|
|
|
|
|
|
|
|
|
|
|
|
(provide 'vlocitemacs)
|
|
;;; vlocitemacs.el ends here
|