Plaster

common-lisp
(defun file-contents (pathname &key (read-function #'read-line)) "Return a list of the contents of PATHNAME by READ-FUNCTION." (with-open-file (stream pathname) (loop for line = (funcall read-function stream nil) while line collect line))) (defun all-symbols-in-file (pathname) "Return all symbols appearing in PATHNAME." (let ((all-symbols nil) (file-contents (file-contents pathname :read-function #'read))) (labels ((recursive-all-symbols (list) (etypecase list (null nil) (atom (when (symbolp list) (push list all-symbols))) (list (progn (recursive-all-symbols (car list)) (recursive-all-symbols (cdr list))))))) (mapc #'recursive-all-symbols file-contents)) (remove-duplicates all-symbols))) (defun all-packages-in-file (pathname) "Return all packages whose symbols appear in PATHNAME." (let ((all-symbols-in-file (all-symbols-in-file pathname))) (remove-duplicates (mapcar #'symbol-package all-symbols-in-file)))) (defvar *package-exclusions* '("COMMON-LISP" "SB-INTROSPECT" "KEYWORD") "List of package names to be excluded from package dependencies as they are either the COMMON-LISP, KEYWORD or lisp implementation packages.") (defun package-dependencies (pathname) "Return the package dependencies of PATHNAME excluding COMMON-LISP and any packages from Lisp implementations." (labels ((dependent-package-p (package) (and (not (member (package-name package) *package-exclusions* :test #'string-equal)) (not (equal package *package*))))) (loop for package in (all-packages-in-file pathname) if (dependent-package-p package) collect package)))