eshell-port-helper

Emacs package for working with OpenBSD ports tree
git clone git://git.konyahin.xyz/eshell-port-helper
Log | Files | Refs | README

commit 02f67668e93625848643f119b8482c894bf5a6f1
Author: Anton Konyahin <me@konyahin.xyz>
Date:   Sat, 29 Apr 2023 20:16:48 +0300

Initial commit

Diffstat:
AREADME.md | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aeshell-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)