diff --git a/lisp/cli/make.el b/lisp/cli/make.el index 70a94765c..b489a10ed 100644 --- a/lisp/cli/make.el +++ b/lisp/cli/make.el @@ -10,8 +10,16 @@ ;; ;;; Variables -;; (defvar doom-make-codeowners () -;; "TODO") +(defvar doom-make-codeowners-file ".github/CODEOWNERS" + "Where to write the CODEOWNERS file, relative to the repo's toplevel.") + +(defvar doom-make-codeowners () + "An alist of codeowners for this project. + +Each entry can either be a string (inserted verbatim, surrounded by newlines) or +a pair of strings (in a cons cell) consisting of: (GLOB . CODEOWNERS). + +The contents of this variable are inserted in reverse.") ;; @@ -21,23 +29,43 @@ "(Re)Generate project files and boilerplate." :partial t) -;; TODO Finish and generalize me -(defstub! (make codeowners) () - "TODO" - (print! (start "Generating CODEOWNERS file")) - (let ((codeowners (doom-path doom-emacs-dir ".github/CODEOWNERS"))) - (with-temp-file codeowners - (insert-file-contents codeowners) - (when (re-search-forward "^# Don't edit this by hand!" nil t) - (goto-char (line-end-position)) - (delete-region (point) (point-max)) - (insert "\n") - (dolist (path (cdr (doom-module-load-path (list doom-modules-dir)))) - (when (string-match "/modules/\\([^/]+\\)/\\([^/]+\\)/$" path) - (insert (format "%-35s @doomemacs/maintainers @doomemacs/%s-%s\n" - (concat (substring (match-string-no-properties 0 path) 1) "*") - (match-string-no-properties 1 path) - (match-string-no-properties 2 path))))))))) +(defcli! (make codeowners) + ((outfile ("-o" "--file" (file stdout)) "Where to write the codeowners file") + (dryrun? ("--dryrun"))) + "Generate (or update) a CODEOWNERS file. + +By default, this means $GIT_WORK_TREE/.github/CODEOWNERS. This will throw an +error if not run in a Git repo. + +OPTIONS: + -o, --file + Pass this option a dash to print the codeowners file to stdout." + (when dryrun? + (setq outfile "-") + (print! (warn "Running dry run; will only print to stdout:"))) + (with-temp-buffer + (let ((codeowners-file + (cond ((equal outfile "-") nil) + (outfile (expand-file-name outfile)) + ((file-name-concat (doom-git-toplevel) doom-make-codeowners-file))))) + (insert "# -*- mode: conf -*-\n" + "# Each line is a file pattern followed by one or more owners.\n" + "# This file was generated by 'doom make codeowners', do not edit it by hand.\n") + (dolist (entry (nreverse doom-make-codeowners)) + (if (stringp entry) + (insert "\n" entry "\n") + (insert (car entry) " " (cdr entry) "\n"))) + (insert "\n# End of CODEOWNERS") + (setq indent-tabs-mode nil) ; align w/ spaces, not tabs + (align-regexp (point-min) (point-max) "/\\(\\s-+\\)@" 1) + (if (null codeowners-file) + (print! "%s" (buffer-string)) + (print! (start "%s codeowners file at: %s") + (if (file-exists-p codeowners-file) + "Regenerated" + "Generated") + (relpath codeowners-file)) + (write-region (buffer-string) nil codeowners-file))))) ;; TODO Finish me (defstub! (make changelog))