FG42/lisp/build.el

163 lines
5.4 KiB
EmacsLisp

;;; FG42 --- The mighty editor for the emacsians -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2024 Sameer Rahmani <lxsameer@gnu.org>
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://devheroes.codes/FG42/FG42
;; Version: 4.0.0
;;
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;
;;; Commentary:
;; This is the builder script that takes the config.json from the input
;; (typically provided by Nix). And generates appropriate Elisp file
;; for the main FG42 Elsip code to load and use.
;;
;; Please note that this file runs with Emacs and not FG42.
;;; Code:
(require 'loaddefs-gen)
(when (not (json-available-p))
(error "Error: libjasson support is missing"))
(defvar file-header " ;;; FG42 --- The mighty editor for the emacsians -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2024 Sameer Rahmani <lxsameer@gnu.org>
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://devheroes.codes/FG42/FG42
;; Version: 4.0.0
;;
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;
;;; Commentary:
;; This is the builder script that takes the config.json from the input
;; (typically provided by Nix). And generates appropriate Elisp file
;; for the main FG42 Elsip code to load and use.
;;
;; Please note that this file runs with Emacs and not FG42.
;;; Code:
;; ============================================================================
;; This file is auto generated by FG42. Don't modify it.
;; ============================================================================
;; Since it is deprecated we can easily avoide other packages to use it
(provide 'cl)
")
(defvar file-footer "
(require 'fg42)
(provide 'fg42_init)
;; fg42_init.el ends here
")
(defvar keys-to-skip '("docstrings" "mimeTypes"))
;; Elisp's hashtables are not functional so I have to store the
;; state like this, Ewwwwww!
(defvar build-state '()
"A list of expressions that will dump in the output at the end.")
(defvar vars ())
(defvar requires ())
(defvar build-output (cadr command-line-args-left))
;;; Build related stuff
(defmacro with-json (var &rest body)
"Read the json file from cli arguments, user VAR run the BODY on it."
(declare (indent defun))
`(let ((input-file (car command-line-args-left)))
(message "[build.el]: Reading the input file: %s" input-file)
(with-temp-buffer
(insert-file-contents input-file)
(let ((,var (json-parse-buffer)))
,@body))))
(defun generate-compile-time-requires (elisp-pkgs)
"Generate a list of `require' forms of ELISP-PKGS for compile time."
(when (> (length elisp-pkgs) 0)
(add-to-list
'requires
`(eval-when-compile
,@(mapcar (lambda (pkg) `(require ',(intern pkg))) elisp-pkgs)))))
(defun generate-generic-vars (k v doc)
"Generate a list of vars for K and value V with docstring DOC."
(add-to-list 'vars `(defvar ,(intern (format "fg42/config/%s" k)) ,v ,doc)))
(defun fg42-config-key-handler (config)
"Generate a lambda to process key/value pairs in CONFIG."
(lambda (k v)
"Handle the FG42 config K and its value V."
(cond
((string= k "requires")
(generate-compile-time-requires v))
((member k keys-to-skip)
(message "[build.el]: Skipping %s..." k))
(t (generate-generic-vars k v (gethash k (gethash "docstrings" config)))))))
(defun fg42-handler (config)
"Handle the CONFIG for FG42.
CONFIG maps to the collective `config' value of Nix modules."
(maphash (fg42-config-key-handler config) config))
(defun handle-conifg-for (k v)
"Find the handler of K and its value V to it."
(funcall (intern (format "%s-handler" k)) v))
(defun handle-top-level (k v)
"Handle the key K and value V form the top level of the JSON data."
(when (not (string= k "fg42"))
(error "Don't know how to handle '%s'" k))
(handle-conifg-for k v))
(with-json j
;; TODO: To make it scale, may be let Nix modules
;; plug into this script. There is a security
;; rist though
(maphash #'handle-top-level j)
(with-temp-file build-output
(insert file-header)
(insert ";; Vars ======")
(mapc (lambda (x) (print x (current-buffer))) vars)
(insert ";; Requires ======")
(mapc (lambda (x) (print x (current-buffer))) requires)
(insert file-footer))
(message "[build.el]: Done!"))
(provide 'build)
;;; build.el ends here