commit 02f67668e93625848643f119b8482c894bf5a6f1
Author: Anton Konyahin <me@konyahin.xyz>
Date: Sat, 29 Apr 2023 20:16:48 +0300
Initial commit
Diffstat:
A | README.md | | | 57 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | eshell-port-helper.el | | | 164 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
2 files changed, 221 insertions(+), 0 deletions(-)
diff --git a/README.md b/README.md
@@ -0,0 +1,57 @@
+# eshell-port-helper
+
+This package provides functions for working with OpenBSD ports tree in
+eshell.
+
+## usage
+
+Copy `eshell-port-helper.el` in your
+`~/.emacs.d/elpa/eshell-port-helper` directory. Then, add to your
+config:
+
+```elisp
+(add-to-list 'load-path "~/.emacs.d/elpa/eshell-port-helper")
+(require 'eshell-port-helper)
+```
+Eval and run `M-x port-jump-to-port`.
+
+You can use `aliases` for short form of commands like this:
+
+```elisp
+(defalias 'pdir 'eshell/port-jump-to-port-dir)
+(defalias 'psrc 'eshell/port-jump-to-src-dir)
+(defalias 'pjump 'eshell/port-jump)
+(defalias 'ppatch 'eshell/port-patch)
+(defalias 'punpatch 'eshell/port-unpatch)
+(defalias 'pmake 'eshell/port-make)
+(defalias 'pupdate 'eshell/port-update-patches)
+```
+
+## variables
+
+`port-dir` - base directory fir port tree
+
+`port-ignore-port-dirs` - this directories will be ignore when we
+search for ports
+
+## functions
+
+`port-jump-to-port` - interactive function for open eshell in specific
+port directory
+
+`eshell/port-jump-to-port-dir port-name` - change directory to port base
+directory
+
+`eshell/port-jump-to-src-dir port-name` - change directory to port's source dir
+
+`eshell/port-jump` - jump between port directory and source directory
+
+`eshell/port-patch file` - make backup file with right suffix and open file
+for editing
+
+`eshell/port-unpatch file` - restore original port file from backup
+
+`eshell/port-make command` - run make command in port directory
+
+`eshell/port-update-patches` - update patches for current port and
+open changed patches in emacs
diff --git a/eshell-port-helper.el b/eshell-port-helper.el
@@ -0,0 +1,164 @@
+;;; eshell-port-helper.el
+
+;; Copyright (C) 2023 Anton Konyahin
+
+;; Author: Anton Konyahin <me@konyahin.xyz>
+;; URL: https://git.konyahin.xyz/eshell-port-helper/log.html
+;; Keywords: eshell port OpenBSD
+;; Version: 0.0.1
+;; Created: 29/04/2023
+
+;; 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 package provides functions for working with OpenBSD ports tree.
+
+;;; Code:
+
+(require 'eshell)
+
+(defvar port-dir "/usr/ports/"
+ "Base directory for port tree")
+
+(defvar port-ignore-port-dirs
+ (list "." "CVS" "tests" "pobj" "distfiles"
+ "infrastructure" "packages" "plist")
+ "This directories will be ignore when we search for ports")
+
+(defun port-string-contain (str args)
+ "Return true if str contain something from args"
+ (cond
+ ((null args) nil)
+ ((string-search (car args) str) t)
+ (t (port-string-contain str (cdr args)))))
+
+(defun port-dir (dir)
+ "Return path to dir in port dir"
+ (concat port-dir dir))
+
+(defun port-in-pobj-p ()
+ "Return non-nil if we in pobj port directory"
+ (string-prefix-p (port-dir "pobj/") (eshell/pwd)))
+
+(defun port-in-port-p ()
+ "Return non-nil if we in port directory"
+ (and (not (port-in-pobj-p))
+ (string-prefix-p port-dir (eshell/pwd))))
+
+(defun port-ports-list ()
+ "Return list of all ports in system"
+ (let* ((filter (lambda (dir)
+ (and (file-directory-p dir)
+ (not (port-string-contain
+ dir port-ignore-port-dirs)))))
+ (category-dirs (seq-filter filter (directory-files port-dir t)))
+ (port-dirs (flatten-list
+ (mapcar (lambda (dir) (directory-files dir t)) category-dirs)))
+ (filtered-dirs (seq-filter filter port-dirs)))
+ (mapcar #'file-name-nondirectory filtered-dirs)))
+
+(defun port-current-port-name ()
+ "Get current port name by current dir path. Return nil
+if we not in port directory."
+ (cond
+ ((port-in-pobj-p)
+ (if (string-match (port-dir "pobj/\\([^/-]*\\)") (eshell/pwd))
+ (match-string 1 (eshell/pwd))))
+ ((port-in-port-p)
+ (if (string-match (port-dir "[^/]*/\\([^/]*\\)/?") (eshell/pwd))
+ (match-string 1 (eshell/pwd))))
+ (t nil)))
+
+(defun port-get-port-dir (port-name)
+ "Get port dir"
+ (let ((dir (file-expand-wildcards
+ (concat (port-dir "*/") port-name))))
+ (cond
+ ((null dir)
+ (message "Can't find such port: %s" port-name)
+ nil)
+ ((equal 1 (length dir))
+ (car dir))
+ (t (message "Find more than one port with name %s" port-name)
+ nil))))
+
+(defun eshell/port-jump-to-port-dir (&optional port-name)
+ "Change current dir to port dir"
+ (let* ((port-name (or port-name (port-current-port-name)))
+ (dir (port-get-port-dir port-name)))
+ (if dir (cd dir))))
+
+(defun eshell/port-jump-to-src-dir (&optional port-name)
+ "Change current dir to port source dir"
+ (let ((port-name (or port-name (port-current-port-name))))
+ (eshell/port-jump-to-port-dir port-name)
+ (cd (string-trim (eshell-command-result "make show=WRKSRC")))))
+
+(defun eshell/port-jump ()
+ "Jump between port directory and source directory"
+ (cond
+ ((port-in-port-p)
+ (eshell/port-jump-to-src-dir))
+ ((port-in-pobj-p)
+ (eshell/port-jump-to-port-dir))
+ (t (message "You are not in port directory"))))
+
+(defun eshell/port-patch (file)
+ "Make backup file with right suffix and open file for editing"
+ (let ((backup (concat file ".orig.port")))
+ (if (not (file-exists-p backup))
+ (copy-file file backup))
+ (find-file file)))
+
+(defun eshell/port-unpatch (file)
+ "Restore original port file from backup"
+ (let ((backup (concat file ".orig.port")))
+ (if (not (file-exists-p backup))
+ (message "This file hasn't backup")
+ (eshell/mv backup file))))
+
+(defun eshell/port-make (command)
+ "Run make command with arguments in port directory"
+ (let ((cur-dir (eshell/pwd)))
+ (eshell/port-jump-to-port-dir)
+ (eshell-do-eval (eshell-parse-command (concat "make " command)) 't)
+ (cd cur-dir)))
+
+(defun port-jump-to-port (port)
+ "Open eshell in port directory"
+ (interactive
+ (list (completing-read "Enter port name: " (port-ports-list))))
+ (let ((default-directory (port-get-port-dir port)))
+ (if default-directory
+ (eshell))))
+
+(defun eshell/port-update-patches ()
+ "Update patches for current port"
+ (with-environment-variables (("EDIT_PATCHES" "Yes")
+ ("EDITOR" "echo files:"))
+ (eshell/port-make "update-patches"))
+ (let ((cur-dir (eshell/pwd))
+ (patch-path (progn
+ (eshell/port-jump-to-port-dir)
+ (string-trim (eshell-command-result "make show=PATCHDIR"))))
+ (output (buffer-substring (eshell-end-of-output) (point-max))))
+ (progn
+ (cd cur-dir)
+ (if (string-match "^files: \\(.*\\)$" output)
+ (mapcar (lambda (patch)
+ (find-file (concat patch-path "/" patch)))
+ (split-string (match-string 1 output)))
+ (message "No changes in patches")))))
+
+(provide 'eshell-port-helper)